Какова цель использования Map в Java
Что проверяют
Знаете ли вы, какую задачу решает Map и, главное, чем отличаются реализации. Сам вопрос простой, поэтому следом почти наверняка спросят, как устроен HashMap внутри и что будет с изменяемым ключом.
Как отвечать
Map хранит пары «ключ-значение» с уникальными ключами и даёт доступ по ключу. Важная деталь: это не наследник Collection, а отдельная иерархия. Коллекциями являются её представления keySet(), values(), entrySet().
Реализацию выбирают по требованиям:
HashMap: поиск и вставка в среднем O(1), порядок не гарантирован, допускает одинnull-ключ. С Java 8 длинная цепочка в корзине превращается в красно-чёрное дерево, и худший случай становится O(log n);LinkedHashMap: помнит порядок вставки, а в режимеaccessOrderпорядок доступа. С переопределённымremoveEldestEntryэто готовый LRU-кэш;TreeMap: ключи отсортированы, операции O(log n), есть навигацияfloorKey,ceilingKey,subMap;ConcurrentHashMap: потокобезопасна без глобальной блокировки,nullне принимает ни в ключах, ни в значениях;EnumMap: для ключей-перечислений, внутри массив;Map.of(...): неизменяемая карта с Java 9, безnull, порядок обхода не определён.
С Java 21 есть SequencedMap с методами firstEntry(), pollLastEntry(), reversed(), его реализуют LinkedHashMap и TreeMap. Из современных методов покажите getOrDefault, computeIfAbsent для группировки и merge для подсчёта: counts.merge(word, 1, Integer::sum).
Где спотыкаются
Говорят, что любая Map работает за O(1). Это средняя оценка для HashMap при нормальном hashCode, у TreeMap логарифм.
Переопределяют equals без hashCode или меняют поле ключа после вставки. Объект лежит в одной корзине, а ищется в другой, и get возвращает null для ключа, который вроде бы есть.
Используют обычный HashMap из нескольких потоков или меняют карту во время обхода. В первом случае теряются записи, во втором вылетает ConcurrentModificationException. Удалять при обходе нужно через iterator.remove() или removeIf на представлении.