Расскажите про интерфейс Map и его популярные реализации, в чем разница и когда что использовать
Что проверяют
Знаете ли вы реализации по существу и умеете ли выбирать под задачу. Перечисление наизусть тут же проверяется вопросами про null, порядок обхода и поведение в нескольких потоках.
Как отвечать
Скажите, что Map не наследует Collection, это отдельный интерфейс пар ключ и значение, а уникальность ключа держится на паре equals и hashCode. Дальше по реализациям.
HashMap: хеш-таблица с корзинами. Коллизии складываются в список, а при их скоплении и достаточном размере таблицы список превращается в дерево, поэтому худший случай не линейный. В среднем доступ за константу. Допускает один ключnullи любые значенияnull. Не потокобезопасен.LinkedHashMap: то же плюс двусвязный список. По умолчанию порядок вставки, но есть режим порядка обращения, и вместе с переопределением удаления самого старого элемента получается готовый кэш вытеснения.TreeMap: красно-чёрное дерево, операции за логарифм, ключи упорядочены поComparableили компаратору. Ключnullне принимает. Даёт навигацию:floorKey,ceilingKey,headMap,subMap.ConcurrentHashMap: для нескольких потоков, блокирует не всю таблицу целиком,nullзапрещён и в ключах, и в значениях, есть атомарныеcomputeIfAbsentиmerge, обход слабо согласован и не бросает исключение при изменении.
Полезно добавить EnumMap для ключей-перечислений и WeakHashMap для кэшей по слабой ссылке.
Где спотыкаются
Кладут в ключ изменяемый объект. Поле, участвующее в hashCode, поменяли после вставки, и запись больше не находится, хотя лежит в таблице.
Считают Hashtable и синхронизированную обёртку равноценной заменой. Они дают атомарность одной операции, но не пары «проверил и положил», и обход всё равно требует внешней блокировки, тогда как ConcurrentHashMap закрывает это атомарными методами.
Обещают константу всегда. Плохой hashCode сгружает всё в одну корзину, а порядок обхода HashMap не совпадает с порядком вставки, даже если на маленьком примере так вышло. Полагаться на это нельзя.