java集合详解 - LinkedHashMap详解

LinkedHashMap 是 Java 集合框架中的一个重要类,它继承自 HashMap,并在其基础上 维护了一个双向链表来记录元素的插入顺序或访问顺序。这使得它既能像 HashMap 一样高效,又能保持可预测的迭代顺序。

LinkedHashMap 的特点

特性说明
键唯一性不允许重复键(基于 equals() 和 hashCode()
有序性默认维护 插入顺序,也可设置为 访问顺序(LRU)
允许 null可以存储 null 键和 null 值
非线程安全多线程环境下需要外部同步
底层实现HashMap + 双向链表(记录顺序)
性能查询、插入、删除 平均 O(1)

注意事项

  1. 线程不安全

    • 多线程环境下应使用 Collections.synchronizedMap 包装:

      Map<String, Integer> syncMap = Collections.synchronizedMap(new LinkedHashMap<>());
    • 或使用 ConcurrentHashMap(但不保证顺序)。

  2. LRU 缓存实现

    • 通过 accessOrder=true + removeEldestEntry 可轻松实现 LRU 缓存。

  3. 内存占用

    • 比 HashMap 占用更多内存(因维护双向链表)。

  4. 迭代性能

    • 遍历比 HashMap 更快(直接按链表顺序访问,无需处理哈希桶)。

典型应用场景

  • 需要保持插入顺序的键值对存储(如配置项加载)。

  • LRU 缓存(最近最少使用算法)。

  • 需要按顺序处理的场景(如日志记录、事件队列)。

  • LinkedHashMap 是 HashMap 的增强版,通过双向链表维护顺序,适用于需要有序键值对的场景。它既保留了 HashMap 的高效性,又提供了可预测的迭代顺序,是 Java 集合框架中非常实用的数据结构。

底层实现

 LinkedHashMap 在 HashMap 的基础上扩展

  • 双向链表的作用

    • 记录元素的插入顺序(默认)或访问顺序(LRU)。

    • 遍历时按链表顺序输出,而非 HashMap 的随机顺序。

public class LinkedHashMap<K,V> extends HashMap<K,V> {
    // 双向链表的头节点
    transient LinkedHashMap.Entry<K,V> head;
    // 双向链表的尾节点
    transient LinkedHashMap.Entry<K,V> tail;
    // 是否按访问顺序排序(true=LRU模式,false=插入顺序)
    final boolean accessOrder;
}

static class Entry<K,V> extends HashMap.Node<K,V> {
    Entry<K,V> before, after; // 双向链表的前驱和后继指针
    Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}

核心方法 

除了继承 HashMap 的方法外,LinkedHashMap 还扩展了以下功能:

方法说明
get(Object key)获取值,若 accessOrder=true 会将该键移到链表末尾(LRU)
removeEldestEntry(Map.Entry<K,V> eldest)钩子方法,可用于实现 LRU 缓存(返回 true 时删除最旧条目)

使用示例

示例 1:基本使用(插入顺序)

LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Orange", 3);

// 遍历顺序与插入顺序一致
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 输出顺序:Apple → Banana → Orange

示例 2:LRU 缓存(访问顺序) 

// 设置 accessOrder=true,启用 LRU 模式
LinkedHashMap<String, Integer> lruCache = new LinkedHashMap<>(16, 0.75f, true) {
    @Override
    protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
        return size() > 3; // 缓存容量为 3,超出时删除最久未访问的条目
    }
};

lruCache.put("A", 1);
lruCache.put("B", 2);
lruCache.put("C", 3);

lruCache.get("A"); // 访问 A,将其移到链表末尾
lruCache.put("D", 4); // 超出容量,删除最旧的 B

System.out.println(lruCache); // 输出:{C=3, A=1, D=4}

 与 HashMap、TreeMap 对比

特性LinkedHashMapHashMapTreeMap
底层实现HashMap + 双向链表哈希表红黑树
顺序插入顺序 或 访问顺序(LRU)无序键的自然排序/自定义排序
查询性能O(1)O(1)O(log n)
插入/删除性能O(1)O(1)O(log n)
允许 null允许 null 键和值允许键不能为 null(除非自定义比较器)
线程安全

如何选择?

  • 需要 键值对 + 插入顺序/访问顺序 → LinkedHashMap

  • 只需要 键值对,不关心顺序 → HashMap

  • 需要 键值对 + 排序 → TreeMap

 传送门: HashMap详解 HashLink详解 ArrayList详解 CopyOnWriteArrayList详解 HashSet详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值