好的,我来给你做一个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:加载因子
  • accessOrdertrue 表示按访问顺序,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️⃣ 使用场景

  1. 保持顺序的 Map:需要遍历时按照插入顺序输出。
  2. LRU 缓存:利用访问顺序和 removeEldestEntry() 实现缓存淘汰策略。
  3. 频繁访问记录:需要记录最近访问顺序的应用场景。
  4. 日志分析、报表生成:按插入顺序保存数据。

总结:

  • LinkedHashMap 是 HashMap 的增强版,增加了顺序维护。
  • 可按插入顺序或访问顺序遍历。
  • 常用于实现 LRU 缓存或有序存储场景。
  • 底层是哈希表 + 双向链表结构。