Какие реализации Map вы используете?
Что проверяют
Знаете ли вы, чем реализации отличаются внутри, а не только их названия. Следом почти всегда идёт «как устроен HashMap» или «что будет, если изменить ключ после put».
Как отвечать
Идите от задачи к реализации:
HashMap: выбор по умолчанию. Массив бакетов, индекс поhashCode()с подмешиванием старших бит. С Java 8 бакет длиннее 8 элементов превращается в красно-чёрное дерево, если таблица не меньше 64. Ёмкость по умолчанию 16,loadFactor0.75, при превышении таблица удваивается. Одинnull-ключ разрешён, порядок не гарантирован;LinkedHashMap:HashMapплюс двусвязный список записей. Хранит порядок вставки, а сaccessOrder = trueпорядок доступа. С переопределённымremoveEldestEntryполучается простой LRU-кэш;TreeMap: красно-чёрное дерево, операции за O(log n), ключи отсортированы поComparableилиComparator. ЧерезNavigableMapдаётfloorKey,ceilingEntry,subMap;ConcurrentHashMap: потокобезопасная без общей блокировки, с Java 8 на CAS и синхронизации отдельного бакета.nullне принимает, атомарныеcomputeIfAbsentиmerge;EnumMap: ключи из enum, внутри массив поordinal(), быстрее и компактнееHashMap;ConcurrentSkipListMap: отсортированная и потокобезопасная одновременно.
Для констант есть Map.of и Map.copyOf: неизменяемые, без null, порядок итерации не гарантирован.
Где спотыкаются
Кладут изменяемый объект ключом и меняют его поля после put. Хэш меняется, запись остаётся в старом бакете и больше не находится. Отсюда требование согласованных equals и hashCode по неизменяемым полям.
Считают Hashtable или Collections.synchronizedMap равноценной заменой ConcurrentHashMap. Они блокируют всю мапу, а составная операция «проверить и положить» всё равно требует внешней синхронизации, если не пользоваться putIfAbsent и compute.
Называют LinkedHashMap готовым LRU-кэшем. Без accessOrder и removeEldestEntry он просто помнит порядок вставки и растёт бесконечно, вытеснять по нему можно разве что по принципу FIFO.