Как HashMap находит место для пары ключ-значение?
- Как устроен HashMap?
- Что такое коллизия в HashMap?
- Почему get в HashMap работает за O(1)?
По hashCode ключа вычисляется индекс корзины в массиве, внутри корзины ключи сравниваются через equals.
- Коллизия — разные ключи в одной корзине: цепочка, при длине 8 и большой таблице — дерево
- При заполнении выше 0.75 таблица удваивается (resize) с перераспределением
А ещё Отсюда требование: equals и hashCode у ключа должны быть согласованы и неизменны
Подробно
HashMap — массив корзин (bucket). При put(key, value):
- вычисляется
key.hashCode(), старшие биты подмешиваются к младшим; - индекс корзины —
hash & (n - 1), где n — размер массива (степень двойки); - если корзина пуста — запись кладётся туда;
- если нет — это коллизия: идём по записям корзины и сравниваем ключи через
equals; совпал — заменяем значение, нет — добавляем запись.
При чтении get(key) путь тот же, поэтому в среднем доступ — O(1).
Коллизии. Записи одной корзины образуют связный список. Если он вырастает до 8 элементов, а таблица не меньше 64 корзин, список превращается в красно-чёрное дерево (treeify) — худший случай становится O(log n) вместо O(n).
Расширение. Когда число записей превышает ёмкость × коэффициент загрузки (по умолчанию 0.75), массив удваивается и записи перераспределяются.
Требование к ключу: равные по equals объекты должны давать одинаковый hashCode, а поля, от которых они зависят, не должны меняться, пока ключ лежит в карте. Иначе запись «потеряется».
Пример
Map<String, Integer> stock = new HashMap<>();
stock.put("apple", 10); // hash("apple") → корзина
stock.get("apple"); // та же корзина → equals → 10Что хотят услышать
- Хеш → индекс корзины → сравнение через equals.
- Что такое коллизия и как она хранится (список, дерево).
- Коэффициент загрузки и resize.
- Требования к ключу: согласованные equals/hashCode, неизменность.
Частые ошибки
- Ожидать от карты предсказуемого порядка обхода.
- Использовать в качестве ключа объект без корректных equals и hashCode.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Хранит пары отсортированными по ключу и ищет двоичным поиском
- ✓Вычисляет хеш ключа, по нему выбирает корзину, а внутри неё сравнивает ключи
- ✗Перебирает все элементы, сравнивая ключи по очереди
- ✗Размещает пары в порядке добавления и запоминает их индексы
Что спросят дальше
- Что происходит при коллизии ключей?
- Почему изменение ключа после добавления ломает поиск?
Разбор темы
- HashMap изнутри: бакеты, treeify, resize
Таблица бакетов, перемешивание хеша и индекс, превращение цепочки в дерево, ресайз и load factor, контракт ключа.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.