Java中的LinkedHashMap用于存储键值对,非常类似于HashMap
类。不同之处在于 LinkedHashMap 维护插入其中的元素的顺序,而 HashMap 是无序的。
在这个 Java 集合教程中,我们将了解 LinkedHashMap 类、它的方法、用例和其他重要细节。
LinkedHashMap 类在 Java 中声明如下。它扩展了HashMap类并实现了Map接口。这里 'K'
是键的类型,'V'
是映射值到键的类型。
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> { //implementation }
了解 Java LinkedHashMap 类的重要事项是:
null
键和多个 null
值。默认情况下,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:A Key:2, Value:B Key:3, Value:C Key:4, Value:D
在访问有序映射中,键根据上次使用 LinkedHashMap 的任何方法访问它们时的访问顺序进行排序。调用 put、putIfAbsent、get、getOrDefault、compute、computeIfAbsent、computeIfPresent 或 merge 方法会导致对相应条目的访问。
键按照从最近最少访问到最近最多访问的顺序排序,并构建 LRU 缓存。
为了创建访问顺序映射,LinkedHashMap 有一个特殊的构造函数参数。当设置为 true
时,LinkedHashMap 保持访问顺序。
//3rd parameter set access order LinkedHashMap<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 pair pairs.get(3); //Access 1st pair pairs.getOrDefault(2, "oops"); pairs.forEach((key, value) -> { System.out.println("Key:"+ key + ", Value:" + value); });
程序输出。
Key:1, Value:A Key:4, Value:D Key:3, Value:C Key:2, Value:B
请注意最近访问的条目如何到达顺序末尾的输出。
LinkedHashMap 有五种类型的构造函数:
'true'
启用访问顺序。'false'
启用插入顺序。这是使用其他构造函数时的默认值行为。关于LinkedHashMap我们应该学习的重要方法如下:
'true'
。'true'
。key
映射的value
。'true'
。用于演示 linkedhashmap 方法用法的 Java 程序。
import java.util.Iterator; import java.util.LinkedHashMap; public class LinkedHashMapExample { public static void main(String[] args) { //3rd parameter set access order LinkedHashMap<Integer, String> pairs = new LinkedHashMap<>(); pairs.put(1, "A"); pairs.put(2, "B"); pairs.put(3, "C"); String value = pairs.get(3); //get method System.out.println(value); value = pairs.getOrDefault(5, "oops"); //getOrDefault method System.out.println(value); //Iteration example Iterator<Integer> iterator = pairs.keySet().iterator(); while(iterator.hasNext()) { Integer key = iterator.next(); System.out.println("Key: " + key + ", Value: " + pairs.get(key)); } //Remove example pairs.remove(3); System.out.println(pairs); System.out.println(pairs.containsKey(1)); //containsKey method System.out.println(pairs.containsValue("B")); //containsValue method } }
程序输出。
C oops Key: 1, Value: A Key: 2, Value: B Key: 3, Value: C {1=A, 2=B} true true
几乎所有需要使用HashMap的情况下,我们都可以使用LinkedHashMap。在功能方面,它可以非常透明地替代 HashMap。
此外,LinkedHashMap 维护插入顺序,这在我们想要维护添加到 Map 的对的顺序时非常有用。
访问有序的 LinkedHashMap 为创建 LRU 缓存 功能提供了一个很好的起点,方法是重写 removeEldestEntry()
方法以在新映射添加到地图。这使您可以使用您定义的某些条件使数据过期。
HashMap 和 LinkedHashMap 以常量时间性能执行添加、删除和包含的基本操作。 LinkedHashMap 比 HashMap 性能差一些,因为它要维护一个双向链表,而 HashMap 只维护一个链表。
另一方面,在 LinkedHashMap 的情况下循环 Map 比 HashMap 稍微快一些,因为所需的时间仅与“大小”成正比。在 HashMap 的情况下,迭代性能与“大小 + 容量”成正比。
HashMap 和 LinkedHashMap 都不是线程安全的,这意味着我们不能直接在多线程应用程序中使用它们来获得一致的结果。我们应该使用 Collections.synchronizedMap(Map map) 方法显式同步它们。
Map<Integer, Integer> numbers = Collections.synchronizedMap(new LinkedHashMap<>()); Map<Integer, Integer> numbers = Collections.synchronizedMap(new HashMap<>());
在 HashMap 的情况下,使用 ConcurrentHashMap 是更可取的,因为它提供了更高的并发度。
基于以上所有信息,我们可以说在大多数情况下选择 HashMap 总是比 LinkedHashMap 更好。仅当我们有某些要求或用例需要维护添加到地图的元素的顺序时,我们才可以更喜欢 LinkedHashMap。
在大多数现实世界的用例中,两者都提供了几乎相同的性能。当我们拥有大量数据时,只有我们应该考虑它们之间的权衡。
快乐学习!!
参考:
地址:https://www.cundage.com/article/linkedhashmap.html