好的,我来给你做一个Java 集合中 LinkedHashMap
的详解,包括概念、特性、底层原理、常用方法和应用场景。
Java 集合 — LinkedHashMap
1️⃣ 基本概念
LinkedHashMap
是 Java 中 Map
接口的一个实现类,它继承自 HashMap
,并在此基础上维护了元素的插入顺序或访问顺序。
特点:
- 有序性:按照插入顺序或访问顺序遍历。
- 键唯一:与
HashMap
相同,key 不可重复。 - 允许 null:可以有一个 null key 和多个 null value。
- 非同步:多线程环境下需手动同步或使用
Collections.synchronizedMap()
。
包路径:
java.util.LinkedHashMap
2️⃣ LinkedHashMap 的特性
特性 | 说明 |
---|---|
继承结构 | 继承自 HashMap ,实现 Map 接口。 |
有序性 | 默认按插入顺序;可通过构造函数设置为按访问顺序。 |
访问顺序 | 若 accessOrder = true,则最近访问的元素排在最前面(可用于 LRU 缓存)。 |
性能 | 查找、插入、删除时间复杂度 O(1),与 HashMap 相同。 |
3️⃣ 构造方法
// 默认构造
LinkedHashMap<K, V> map = new LinkedHashMap<>();
// 指定初始容量和加载因子
LinkedHashMap<K, V> map = new LinkedHashMap<>(int initialCapacity, float loadFactor);
// 按访问顺序构造
LinkedHashMap<K, V> map = new LinkedHashMap<>(16, 0.75f, true);
initialCapacity
:初始容量loadFactor
:加载因子accessOrder
:true
表示按访问顺序,false
(默认)按插入顺序
4️⃣ 底层原理
4.1 数据结构
- 链表 + 哈希表:
- 哈希表用于快速定位键值对
- 双向链表用于维护顺序(插入顺序或访问顺序)
4.2 遍历顺序
- 插入顺序:元素按插入时的顺序遍历。
- 访问顺序:当 accessOrder = true 时,每次访问元素(get 或 put)都会把该元素移动到链表末尾。
4.3 LRU 缓存实现
可以通过覆盖 removeEldestEntry()
方法实现:
LinkedHashMap<Integer, String> cache = new LinkedHashMap<Integer, String>(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, String> eldest) {
return size() > 3; // 超过容量 3 时删除最老元素
}
};
5️⃣ 常用方法
方法 | 说明 |
---|---|
put(K key, V value) | 添加元素 |
get(Object key) | 获取元素,访问顺序时会更新链表顺序 |
remove(Object key) | 删除元素 |
containsKey(Object key) | 判断 key 是否存在 |
containsValue(Object value) | 判断 value 是否存在 |
keySet() | 返回所有 key 的集合 |
values() | 返回所有 value 的集合 |
entrySet() | 返回所有键值对集合 |
clear() | 清空 Map |
6️⃣ 示例代码
6.1 插入顺序
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
// 输出顺序:A -> B -> C
6.2 访问顺序(LRU)
LinkedHashMap<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.get("A"); // 访问 A,A 移动到末尾
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey());
}
// 输出顺序:B, C, A
6.3 LRU 缓存示例
LinkedHashMap<Integer, String> cache = new LinkedHashMap<Integer, String>(3, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry<Integer, String> eldest) {
return size() > 3;
}
};
cache.put(1, "A");
cache.put(2, "B");
cache.put(3, "C");
cache.get(1);
cache.put(4, "D"); // 自动删除最久未访问的 key=2
7️⃣ 使用场景
- 保持顺序的 Map:需要遍历时按照插入顺序输出。
- LRU 缓存:利用访问顺序和
removeEldestEntry()
实现缓存淘汰策略。 - 频繁访问记录:需要记录最近访问顺序的应用场景。
- 日志分析、报表生成:按插入顺序保存数据。
总结:
LinkedHashMap
是HashMap
的增强版,增加了顺序维护。- 可按插入顺序或访问顺序遍历。
- 常用于实现 LRU 缓存或有序存储场景。
- 底层是哈希表 + 双向链表结构。
发表回复