Java 中的 LinkedHashMap 用于存储与 HashMap
类非常相似的键值对。
不同的是,LinkedHashMap 维护插入元素的顺序,而HashMap 是无序的。
LinkedHashMap 的方法
- void clear():它从地图中删除所有键值对。
- void size():它返回此映射中存在的键值对的数量。
- void isEmpty():如果此映射不包含键值映射,则返回 true..
- boolean containsKey(Object key):如果映射中存在指定的键,则返回“true”。
- boolean containsValue(Object key):如果指定值映射到映射中的至少一个键,则返回“true”。
- Object get(Object key):它检索由指定的
key
映射的value
。 - Object remove(Object key):它从映射中删除指定键的键值对(如果存在)。
- boolean removeEldestEntry(Map.Entry eldest):当映射从访问有序映射中删除其最旧的条目时,它返回“真”。
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 更可取,因为它提供了更高程度的并发性。
LinkedHashMap 的特性
- 它存储类似于 HashMap 的键值对。
- 它只包含唯一键。不允许使用重复的密钥。
- 它可能有一个
null
键和多个null
值。 - 它通过将元素添加到内部管理的双向链表来维护插入其中的 K、V 对的顺序。
插入有序的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:A Key:2, Value:B Key:3, Value:C Key:4, Value:D
访问有序的 LinkedHashMap
在访问有序映射中,键根据上次使用 LinkedHashMap 的任何方法访问时的访问顺序进行排序。
调用 put、putIfAbsent、get、getOrDefault、compute、computeIfAbsent、computeIfPresent 或者 merge 方法会导致对相应条目的访问。
键从最近最少访问使用到最近访问并构建 LRU 缓存。
为了创建访问顺序映射,LinkedHashMap 有一个特殊的构造函数参数。
当设置为 true
时,LinkedHashMap 维护访问顺序。
// 第三个参数设置访问的顺序 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"); // 访问第3个键值对 pairs.get(3); // 访问第1个键值对 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
Java LinkedHashMap 示例
import java.util.Iterator; import java.util.LinkedHashMap; public class LinkedHashMapExample { public static void main(String[] args) { // 第三个参数设置访问顺序 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); // 迭代 Iterator<Integer> iterator = pairs.keySet().iterator(); while(iterator.hasNext()) { Integer key = iterator.next(); System.out.println("Key: " + key + ", Value: " + pairs.get(key)); } // 删除 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
Java LinkedHashMap 的层次结构
LinkedHashMap 类在 Java 中声明如下。
它扩展了 HashMap 类并实现了 Map 接口。
这里“K”是键的类型,“V”是映射到键的值的类型。
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> { //implementation }
LinkedHashMap 构造函数
LinkedHashMap 有五种类型的构造函数:
- LinkedHashMap():使用默认初始容量 (16) 和负载因子 (0.75) 初始化默认 LinkedHashMap 实现。
- LinkedHashMap(int capacity):用指定的容量和负载因子 (0.75) 初始化 LinkedHashMap。
- LinkedHashMap(Map map):初始化一个LinkedHashMap,映射关系与指定的map相同。
- LinkedHashMap(int capacity, float fillRatio):用指定的初始容量和负载因子初始化LinkedHashMap。
- LinkedHashMap(int capacity, float fillRatio, boolean Order):初始化LinkedHashMap的容量和填充率,以及是否保持插入顺序或者访问顺序。
'true'
启用访问顺序。'false'
启用插入顺序。这是使用其他构造函数时的默认值行为。