Ответ
LinkedHashMap сохраняет порядок итерации по элементам, который по умолчанию соответствует порядку вставки (insertion-order).
Ключевые особенности:
- Порядок вставки: Элементы перебираются в том порядке, в котором они были добавлены в карту.
- Порядок доступа (LRU-подобный): При создании с флагом
accessOrder = trueпорядок итерации меняется при каждом обращении (get,put). Последний использованный элемент перемещается в конец. - Реализация: Расширяет
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, где они могут вылезти в каком угодно пиздецком порядке.
Вот на что смотреть, ёпта:
- Порядок вставки (дефолтный режим). Засунул «яблоко», потом «грушу», потом «арбуз» — так их и получишь обратно. Никаких сюрпризов, всё чётко, как в аптеке.
- Порядок доступа (режим хитрожопого кэша). А вот если ему специальный флажок
accessOrder = trueпередать при создании, то тут начинается магия. Каждый раз, когда ты к элементу обращаешься (прочитал или обновил), он, сука, переползает в самый конец списка. Получается «последний использованный — в хвост». Прямо как в жизни: кто активнее всех суетится, того все и замечают в конце. - Как устроен. Да внутри всё тот же добрый 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), где самые старые, неиспользуемые элементы, блядь, выкидываются. Удобная хуйня, если знать, как ей пользоваться.