Чем LinkedHashMap отличается от HashMap в Java?

«Чем LinkedHashMap отличается от HashMap в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

LinkedHashMap<K, V> — это реализация интерфейса Map, которая:

  1. Сохраняет порядок добавления элементов (по умолчанию) или порядок последнего доступа к ним.
  2. Наследуется от HashMap, используя его внутреннюю хеш-таблицу для быстрого доступа.
  3. Добавляет двусвязный список, соединяющий все записи для поддержания порядка.
Сравнение с HashMap: Особенность HashMap LinkedHashMap
Порядок итерации Не гарантирован, может меняться Гарантирован (порядок вставки или доступа)
Производительность Чуть быстрее на put()/get() Чуть медленнее из-за поддержки списка
Память Меньше накладных расходов Больше из-за хранения ссылок before/after
Итерация O(capacity) в худшем случае O(n), всегда пропорционально размеру

Пример: порядок вставки (по умолчанию)

Map<String, Integer> map = new LinkedHashMap<>();
map.put("z", 3);
map.put("a", 1);
map.put("b", 2);
// Итерация: z=3, a=1, b=2 (сохранен порядок put)
System.out.println(map); 

Пример: LRU-кэш на основе порядка доступа

// Третий параметр `true` включает режим порядка доступа (access-order)
Map<String, String> lruCache = new LinkedHashMap<>(16, 0.75f, true) {
    @Override
    protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
        return size() > 3; // Удаляет самую старую запись при превышении лимита
    }
};

lruCache.put("1", "A");
lruCache.put("2", "B");
lruCache.put("3", "C");
lruCache.get("1"); // Обращение к "1" перемещает её в конец (самую новую)
lruCache.put("4", "D"); // Удалится "2", так как она стала самой старой (менее используемой)
// Состояние кэша: ["3"="C", "1"="A", "4"="D"]