LinkedHashMap в Java используется для хранения пар ключ-значение, очень похоже на класс HashMap. Разница в том, что LinkedHashMap сохраняет порядок вставленных в него элементов, тогда как HashMap не упорядочен.
В этом руководстве по коллекции Java мы узнаем о классе LinkedHashMap, его методах, вариантах использования и других важных деталях.
1. Иерархия LinkedHashMap
Класс LinkedHashMap в Java объявлен следующим образом. Он расширяет класс HashMap и реализует интерфейс Map. Здесь «K» — тип ключей, а «V» — тип сопоставленных значений с ключами.
public class LinkedHashMap<K,V>extends HashMap<K,V>implements Map<K,V>{//implementation}
2. Возможности LinkedHashMap
Вот что важно знать о классе Java LinkedHashMap:
- Он хранит пары ключ-значение, аналогичные HashMap.
- Он содержит только уникальные ключи. Дубликаты ключей не допускаются.
- Он может иметь один нулевой ключ и несколько нулевых значений.
- Он сохраняет порядок пар K,V, вставленных в него, путем добавления элементов во внутренне управляемый двусвязный список.
2.1. Вставка упорядоченного LinkedHashMap
По умолчанию LinkedHashMap упорядочен по вставке. Он сохраняет порядок элементов, когда они были добавлены в него. При итерации по LinkedHashMap мы получаем пары KV в точном порядке их добавления.
LinkedHashMap<Integer, String> pairs = new LinkedHashMap<>();pairs.put(1, "A");pairs.put(2, "B");pairs.put(3, "C");pairs.put(4, "D");pairs.forEach((key, value) -> {System.out.println("Key:"+ key + ", Value:" + value);});
Вывод программы.
Key:1, Value:AKey:2, Value:BKey:3, Value:CKey:4, Value:D
2.2. Доступ к упорядоченному LinkedHashMap
В карте доступа ключи сортируются на основе порядка доступа, когда к ним последний раз обращались с помощью любого метода LinkedHashMap. Вызов методов put, putIfAbsent, get, getOrDefault, compute, computeIfAbsent, computeIfPresent или merge приводит к доступу к соответствующей записи.
Ключи сортируются от наиболее часто используемых до наиболее часто используемых и формируют кэш LRU.
Для создания карты порядка доступа LinkedHashMap имеет специальный аргумент конструктора. При установке значения true LinkedHashMap сохраняет порядок доступа.
//3rd parameter set access orderLinkedHashMap<Integer, String> pairs = new LinkedHashMap<>(2, .75f, true);pairs.put(1, "A");pairs.put(2, "B");pairs.put(3, "C");pairs.put(4, "D");//Access 3rd pairpairs.get(3);//Access 1st pairpairs.getOrDefault(2, "oops");pairs.forEach((key, value) -> {System.out.println("Key:"+ key + ", Value:" + value);});
Вывод программы.
Key:1, Value:AKey:4, Value:DKey:3, Value:CKey:2, Value:B
Обратите внимание на вывод, в котором последняя использованная запись перемещается в конец порядка.
3. Конструкторы LinkedHashMap
LinkedHashMap имеет пять типов конструкторов:
- LinkedHashMap(): инициализирует реализацию LinkedHashMap по умолчанию с начальной емкостью(16) и коэффициентом загрузки(0,75).
- LinkedHashMap(int capacity): инициализирует LinkedHashMap с указанной емкостью и коэффициентом загрузки(0,75).
- LinkedHashMap(Map map): инициализирует LinkedHashMap с теми же сопоставлениями, что и указанная карта.
- LinkedHashMap(int capacity, float fillRatio): инициализирует LinkedHashMap с указанной начальной емкостью и коэффициентом загрузки.
- LinkedHashMap(int capacity, float fillRatio, boolean Order): инициализирует как емкость, так и коэффициент заполнения для LinkedHashMap, а также указывает, следует ли поддерживать порядок вставки или порядок доступа.
- «true» включает порядок доступа.
- ‘false’ включить порядок вставки. Это поведение значения по умолчанию при использовании других конструкторов.
4. Методы LinkedHashMap
Ниже приведены важные методы, которые нам следует изучить в LinkedHashMap:
- void clear(): удаляет все пары ключ-значение из карты.
- void size(): возвращает количество пар ключ-значение, присутствующих в этой карте.
- void isEmpty(): возвращает true, если эта карта не содержит сопоставлений ключ-значение.
- boolean containsKey(Object key): возвращает «true», если указанный ключ присутствует в карте.
- boolean containsValue(Object key): возвращает «true», если указанное значение сопоставлено хотя бы с одним ключом в карте.
- Object get(Object key): извлекает значение, сопоставленное указанному ключу.
- Object remove(Object key): удаляет пару ключ-значение для указанного ключа из карты, если она присутствует.
- boolean removeEldestEntry(Map.Entry eldest): возвращает значение «true», когда карта удаляет свою самую старую запись из упорядоченной карты доступа.
4.1 Пример Java LinkedHashMap
Программа на Java, демонстрирующая использование методов linkedhashmap.
import java.util.Iterator;import java.util.LinkedHashMap;public class LinkedHashMapExample{public static void main(String[] args){//3rd parameter set access orderLinkedHashMap<Integer, String> pairs = new LinkedHashMap<>();pairs.put(1, "A");pairs.put(2, "B");pairs.put(3, "C");String value = pairs.get(3); //get methodSystem.out.println(value);value = pairs.getOrDefault(5, "oops"); //getOrDefault methodSystem.out.println(value);//Iteration exampleIterator<Integer> iterator = pairs.keySet().iterator();while(iterator.hasNext()) {Integer key = iterator.next();System.out.println("Key: " + key + ", Value: " + pairs.get(key));}//Remove examplepairs.remove(3);System.out.println(pairs);System.out.println(pairs.containsKey(1)); //containsKey methodSystem.out.println(pairs.containsValue("B")); //containsValue method}}
Вывод программы.
CoopsKey: 1, Value: AKey: 2, Value: BKey: 3, Value: C{1=A, 2=B}truetrue
5. Варианты использования LinkedHashMap
Мы можем использовать LinkedHashMap почти во всех ситуациях, где нам требуется использовать HashMap. С точки зрения функциональности он может заменить HashMap очень прозрачно.
Кроме того, LinkedHashMap сохраняет порядок вставки, что делает его очень полезным, когда мы хотим сохранить порядок пар, добавляемых в карту.
Доступ упорядоченный LinkedHashMap обеспечивает отличную отправную точку для создания функциональности LRU Cache путем переопределения метода removeEldestEntry() для наложения политики автоматического удаления устаревших данных при добавлении новых сопоставлений в карту. Это позволяет вам устаревать данные, используя некоторые критерии, которые вы определяете.
6. Производительность LinkedHashMap
HashMap и LinkedHashMap выполняют основные операции добавления, удаления и содержания с постоянной производительностью. LinkedHashMap работает немного хуже, чем HashMap, поскольку ему приходится поддерживать двусвязный список, а HashMap поддерживает только связанный список.
С другой стороны, цикл по Map в случае LinkedHashMap немного быстрее, чем HashMap, поскольку требуемое время пропорционально только ‘size’. В случае HashMap производительность итерации пропорциональна ‘size + capacity’.
7. Параллелизм в LinkedHashMap
HashMap и LinkedHashMap не являются потокобезопасными, что означает, что мы не можем напрямую использовать их в многопоточном приложении для получения согласованных результатов. Мы должны синхронизировать их явно, используя метод Collections.synchronizedMap(Map map).
Map<Integer, Integer> numbers = Collections.synchronizedMap(new LinkedHashMap<>());Map<Integer, Integer> numbers = Collections.synchronizedMap(new HashMap<>());
В случае HashMap использование ConcurrentHashMap более целесообразно, поскольку он обеспечивает гораздо более высокую степень параллелизма.
8. Заключение
На основании всей вышеизложенной информации можно сказать, что всегда лучше выбирать HashMap вместо LinkedHashMap в большинстве сценариев. Мы можем предпочесть LinkedHashMap только тогда, когда у нас есть определенные требования или вариант использования, требующий сохранения порядка элементов, добавляемых в карту.
Оба обеспечивают примерно одинаковую производительность в большинстве реальных сценариев использования. Когда у нас очень большой объем данных, только тогда мы должны рассматривать компромиссы между ними.
Ссылка: