Какая реализация Map в Java сохраняет порядок вставки элементов?

Ответ

LinkedHashMap<K, V> — реализация Map, которая сохраняет порядок вставки пар ключ-значение (или порядок доступа, если настроено).

Принцип работы: Внутри, помимо структуры данных на основе хэш-таблицы, LinkedHashMap поддерживает двусвязный список, который фиксирует последовательность элементов.

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

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

for (String key : map.keySet()) {
    System.out.println(key); // Гарантированный вывод: z, a, b
}

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

  • Порядок по умолчанию: Порядок вставки (insertion-order).
  • Порядок доступа: Можно создать с флагом accessOrder = true, тогда при каждом обращении (get, put) элемент перемещается в конец, реализуя основу для LRU-кэша.
  • Производительность: Немного медленнее HashMap из-за накладных расходов на поддержание списка, но быстрее TreeMap.
  • Итерация: Итерация по LinkedHashMap выполняется за O(n) и предсказуема.

Ответ 18+ 🔞

Да ты посмотри, что за зверь такой — LinkedHashMap<K, V>! Это, блядь, не просто какая-то там мапа, это мапа с памятью, сука! Она запоминает, в каком порядке ты туда всё пихал, и так же по порядку и отдаёт. Не как HashMap, который там внутри всё перетасует по-своему, а чётко, как ты заносил.

Как оно, блядь, работает? Да очень просто, ёпта! Помимо обычной хэш-таблицы, где всё быстро ищется, там внутри ещё двусвязный список прикручен. Этот список, сука, как верёвочка, на которую нанизаны все твои записи в порядке поступления. Красота!

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

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

for (String key : map.keySet()) {
    System.out.println(key); // Гарантированный вывод: z, a, b
}

Видишь? Вывело именно z, a, b. Никаких сюрпризов! HashMap мог бы выдать a, b, z или ещё какую хуйню.

А теперь главные фишки, блядь:

  • Порядок по дефолту: Порядок вставки, он же insertion-order. Как пихал, так и получишь обратно.
  • Порядок доступа — вот где магия! Можно создать эту штуку с флажком accessOrder = true. И тогда, ёбана-матрешка, при каждом обращении (даже простой get) элемент уезжает в самый конец списка! Из этого, блядь, LRU-кэши делают — последнее использованное в конце, самое старое и неиспользуемое в начале. Гениально, сука!
  • Скорость: Чуть-чуть медленнее, чем HashMap, потому что список надо поддерживать. Но всё равно, блядь, в разы шустрее, чем TreeMap с его сортировками.
  • Перебор: Итерация по нему — это O(n) и полная предсказуемость. Никаких сюрпризов, всё чётко, как по ниточке.

В общем, если тебе нужен HashMap, но чтобы ещё и порядок помнил — это твой выбор, чувак. Просто красавец, а не структура!