Какой порядок элементов поддерживает LinkedHashMap в Java?

Ответ

LinkedHashMap сохраняет порядок итерации по элементам, который по умолчанию соответствует порядку вставки (insertion-order).

Ключевые особенности:

  1. Порядок вставки: Элементы перебираются в том порядке, в котором они были добавлены в карту.
  2. Порядок доступа (LRU-подобный): При создании с флагом accessOrder = true порядок итерации меняется при каждом обращении (get, put). Последний использованный элемент перемещается в конец.
  3. Реализация: Расширяет HashMap, добавляя двусвязный список для поддержания порядка.

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

Map<String, Integer> map = new LinkedHashMap<>();
map.put("z", 1);
map.put("a", 2);
map.put("m", 3);

for (String key : map.keySet()) {
    System.out.print(key + " "); // Вывод: z a m
}

Пример 2: Порядок доступа (LRU)

// Третий параметр `true` включает режим порядка доступа
Map<String, Integer> lruMap = new LinkedHashMap<>(16, 0.75f, true);
lruMap.put("a", 1);
lruMap.put("b", 2);
lruMap.put("c", 3);

lruMap.get("a"); // Обращение к "a" перемещает её в конец

for (String key : lruMap.keySet()) {
    System.out.print(key + " "); // Вывод: b c a
}

Это поведение полезно для создания простых LRU-кэшей (Least Recently Used).

Ответ 18+ 🔞

А, слушай, про эту штуку, LinkedHashMap, да? Ну, это типа как обычный HashMap, только с прибамбасом, с порядком, блядь. Представь себе очередь в столовую: кто первый пришёл, тот первый и получил свою пиздюлину из котла. Вот и он так же — запомнил, в каком порядке ты элементы засовывал, и в таком же, сука, порядке их тебе и отдаст при переборе. Не как обычный HashMap, где они могут вылезти в каком угодно пиздецком порядке.

Вот на что смотреть, ёпта:

  1. Порядок вставки (дефолтный режим). Засунул «яблоко», потом «грушу», потом «арбуз» — так их и получишь обратно. Никаких сюрпризов, всё чётко, как в аптеке.
  2. Порядок доступа (режим хитрожопого кэша). А вот если ему специальный флажок accessOrder = true передать при создании, то тут начинается магия. Каждый раз, когда ты к элементу обращаешься (прочитал или обновил), он, сука, переползает в самый конец списка. Получается «последний использованный — в хвост». Прямо как в жизни: кто активнее всех суетится, того все и замечают в конце.
  3. Как устроен. Да внутри всё тот же добрый HashMap, но к нему прикрутили, блядь, двусвязный список, который эти порядки и поддерживает. Не ахти какая сложность, но работает.

Смотри, как это выглядит в коде, на примерах:

Пример 1: Тупо порядок вставки (как все нормальные люди используют)

Map<String, Integer> map = new LinkedHashMap<>();
map.put("z", 1);
map.put("a", 2);
map.put("m", 3);

for (String key : map.keySet()) {
    System.out.print(key + " "); // Выведет ровно так, как заносил: z a m
}

Видишь? Никаких неожиданностей. z, потом a, потом m. Красота, ебать мои старые костыли.

Пример 2: Включили режим хитрой жопы (access order)

// Смотри, третий параметр `true` — это и есть волшебный ключ
Map<String, Integer> lruMap = new LinkedHashMap<>(16, 0.75f, true);
lruMap.put("a", 1);
lruMap.put("b", 2);
lruMap.put("c", 3);

lruMap.get("a"); // Тут мы, блядь, ткнули в элемент "a"

for (String key : lruMap.keySet()) {
    System.out.print(key + " "); // И он уполз в конец! Вывод: b c a
}

Вот она, магия! Сначала порядок был a, b, c. Но мы потрогали «a» — и она сразу стала последней, хитрая жопа. b, c, a. Это, кстати, основа для простенького LRU-кэша (Least Recently Used), где самые старые, неиспользуемые элементы, блядь, выкидываются. Удобная хуйня, если знать, как ей пользоваться.