LinkedHashMap
定位说明
Map 系列第 3 篇。HashMap + 双向链表:accessOrder=true 就是 LRU 缓存的现成地基(配 removeEldestEntry),本篇含完整 LRU 实现示例。
LinkedHashMap 是什么?
LinkedHashMap 是 Java 集合框架中 HashMap 的一个子类,底层基于哈希表 + 双向链表,它不仅具备 HashMap 的快速查找特性(平均
O(1)),还可以保持元素的插入顺序或访问顺序。
它继承了
HashMap的所有 API,但对遍历顺序进行了增强。
核心特性(区别于 HashMap)
| 特性 | LinkedHashMap 说明 |
|---|---|
| 顺序可控 | 可以按 插入顺序 或 访问顺序 进行遍历 |
| 基于双向链表 | 在每个节点中维护 before 和 after 指针,维护元素顺序 |
| 查询效率 | 和 HashMap 一样,查找时间复杂度为 O(1) |
| 插入/删除效率 | 略低于 HashMap,维护顺序结构需额外指针操作 |
| 线程安全 | 非线程安全,需要手动加锁或使用 Collections.synchronizedMap() 包装 |
| null 支持 | 支持一个 null 键和多个 null 值 |
常用构造函数
// 默认按插入顺序排序
LinkedHashMap<K, V> map = new LinkedHashMap<>();
// 指定初始容量、负载因子
LinkedHashMap<K, V> map = new LinkedHashMap<>(16, 0.75f);
// accessOrder = true 表示按访问顺序排序(用于 LRU 缓存)
LinkedHashMap<K, V> map = new LinkedHashMap<>(16, 0.75f, true);
使用示例
插入顺序遍历(默认)
Map<String, Integer> map = new LinkedHashMap<>();
map.put("A", 1);
map.put("C", 3);
map.put("B", 2);
for (String key : map.keySet()) {
System.out.print(key + " "); // 输出顺序:A C B
}
访问顺序遍历(accessOrder = true)
Map<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.get("A");
map.get("C");
for (String key : map.keySet()) {
System.out.print(key + " "); // 输出顺序:B A C(按访问顺序)
}
实际应用场景
保留插入顺序(日志记录、数据导出)
使用 LinkedHashMap 可以按用户插入的顺序输出数据,常用于:
- 构建 JSON 时保持字段顺序
- 数据库同步、配置加载按原顺序处理
实现 LRU 缓存(最近最少使用)
利用 accessOrder = true + 重写 removeEldestEntry():
class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75f, true); // accessOrder = true
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity; // 超出容量自动移除最旧访问的
}
}
使用示例:
LRUCache<Integer, String> cache = new LRUCache<>(3);
cache.put(1, "A");
cache.put(2, "B");
cache.put(3, "C");
cache.get(1);
cache.put(4, "D");
System.out.println(cache.keySet()); // 输出 [3, 1, 4]
使用注意事项
| 注意点 | 说明 |
|---|---|
| 不是线程安全 | 多线程场景使用 Collections.synchronizedMap() 或 ConcurrentHashMap |
| null 键值 | 和 HashMap 一样,允许一个 null 键,多个 null 值 |
| 不保证绝对有序性 | 只有 accessOrder=false 时才完全按插入顺序;设置为 true 后顺序会因访问而变化 |
| 删除最旧元素需重写 removeEldestEntry() | 用于实现缓存淘汰策略 |
总结一句话
LinkedHashMap是结合了HashMap快速查找 和双向链表顺序控制能力的集合类,适用于需要有序遍历或实现 LRU 缓存等高级需求的场景。
LinkedHashMap源码剖析
⬅️ HashMap源码解析 🏠 00-Java ➡️ LinkedHashMap源码剖析
💬 评论