LinkedHashMap

ℹ️定位说明

Map 系列第 3 篇。HashMap + 双向链表:accessOrder=true 就是 LRU 缓存的现成地基(配 removeEldestEntry),本篇含完整 LRU 实现示例。

LinkedHashMap 是什么?

LinkedHashMap 是 Java 集合框架中 HashMap 的一个子类,底层基于哈希表 + 双向链表,它不仅具备 HashMap 的快速查找特性(平均 O(1)),还可以保持元素的插入顺序或访问顺序

它继承了 HashMap 的所有 API,但对遍历顺序进行了增强。

核心特性(区别于 HashMap)

特性 LinkedHashMap 说明
顺序可控 可以按 插入顺序访问顺序 进行遍历
基于双向链表 在每个节点中维护 beforeafter 指针,维护元素顺序
查询效率 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源码剖析