LinkedHashMap:Java界的秩序控,是时候重新认识它了!

admin 2025年6月1日02:20:05评论15 views字数 3379阅读11分15秒阅读模式

LinkedHashMap?HashMap的“私生子”?

原文说LinkedHashMap是HashMap的子类,还引入了双向链表来维护顺序…等等,这说法太官方了! 换个角度:如果HashMap是Java Map家族里的“混沌无序之王”,那LinkedHashMap就是追求“井井有条”的秩序控!它在HashMap的骨架上,硬生生加了一条“时间线”,让你能按照插入顺序或者访问顺序来遍历数据。 就像你在硬盘上整理文件,是按时间排序还是按访问频率排序,全看你的心情!

以下是LinkedHashMap的继承与实现关系源码?别闹了,直接看它怎么“继承”HashMap的“皇位”更重要:

public class LinkedHashMap<K,V>       extends HashMap<K,V>       implements Map<K,V>

LinkedHashMap的“三宗罪”与“一桩美德”

  1. 有序?别激动,这“有序”是有代价的!LinkedHashMap用双向链表“绑架”了key-value,虽然访问起来有条不紊,但…

  2. 速度慢?没错!增删改查,HashMap敢说第二,没人敢说第一(除了专门优化的ConcurrentHashMap)。 LinkedHashMap?乖乖排队维护你的链表去吧!

  3. 底层复杂?数组+链表+红黑树+双向链表…这数据结构,简直是“俄罗斯套娃”!

那它还有啥用? 别急,LinkedHashMap的“一桩美德”足以让它在某些场景下封神:它能记住你操作数据的顺序! 这在缓存淘汰、访问日志等场景下,简直是神器!

源码?先别睡着!(JDK17版“解剖”)

Entry:HashMap.Node的“豪华升级版”

HashMap的Node是单向链表,LinkedHashMap的Entry则直接上了双向链表!

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的Node是“单身宿舍”,LinkedHashMap的Entry是“豪华套间”,自带前后指针,方便“串门”!

插入新元素?没啥黑科技,就是把新“套间”扔到链表尾巴上。 访问已有节点? 如果你开启了“访问顺序模式”,那这个节点就会被“荣升”到链表尾部,享受“C位待遇”!

put?HashMap的“马仔”

void afterNodeInsertion(boolean evict) { // 在HashMap中被回调       LinkedHashMap.Entry<K,V> first;       if (evict && (first = head) != null && removeEldestEntry(first)) {           K key = first.key;           removeNode(hash(key), key, null, false, true);       }   }

LinkedHashMap自己不干脏活累活,直接让HashMap干! put完之后,它负责维护链表顺序,就像一个“善后处理小组”。

get?“暗藏玄机”的访问顺序调整

public V get(Object key) {       Node<K,V> e;       if ((e = getNode(key)) == null)           return null;       if (accessOrder)           afterNodeAccess(e);       return e.value;   }

void afterNodeAccess(Node<K,V> e) { // 移动访问节点到链表尾部       LinkedHashMap.Entry<K,V> last;       if (accessOrder && (last = tail) != e) {           LinkedHashMap.Entry<K,V> p = (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;           p.after = null;           if (b == null)               head = a;           else               b.after = a;           if (a != null)               a.before = b;           else               last = b;           if (last == null)               head = p;           else {               p.before = last;               last.after = p;           }           tail = p;           ++modCount;       }   }

重点是accessOrder! 开启它,每次get都会触发afterNodeAccess,把被访问的节点“踢”到链表尾部。 这就是LRU缓存的核心机制!

LinkedHashMap的“进化史”?一部“缝缝补补”的血泪史

JDK1.4-1.7: “青春期”的烦恼

纯数组+链表+双向链表,简单粗暴! 但hash冲突一多,链表就成了性能瓶颈。

JDK8: “中年危机”与“红黑树”的救赎

HashMap引入了红黑树,LinkedHashMap也赶紧“缝缝补补”,重写相关方法,保证链表的一致性。

JDK9+: “老年养生”与“迭代器”的安全性

增强fail-fast机制,防止多线程并发修改导致的数据不一致。

应用场景?LinkedHashMap的“高光时刻”

LRU缓存: “过期网红”的末日

public class LRUCache<K,V> extends LinkedHashMap<K,V> {       private final int maxCapacity;          public LRUCache(int maxCapacity) {           super(maxCapacity, 0.75f, true);           this.maxCapacity = maxCapacity;       }          @Override       protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {           return size() > maxCapacity;       }   }

开启accessOrder,重写removeEldestEntry,当容量超过最大值时,链表头部的“老家伙”就会被无情地踢出去!

访问轨迹记录: “谁动了我的奶酪?”

LinkedHashMap<String, Long> accessLog = new LinkedHashMap<>(100, 0.75f, true) {       @Override       protected boolean removeEldestEntry(Map.Entry<String, Long> eldest) {           return size() > 50; // 仅保留最近50次访问记录       }   };

记录用户访问顺序,分析用户行为,简直是“用户画像”的利器!

性能调优?别指望它能“飞”起来

  1. 容量初始化: 预估你的数据量,给它一个合适的“家”,避免频繁扩容。

  2. 负载因子: 查询多?那就降低负载因子,减少hash冲突!

  3. 并发? 别碰! 除非你用Collections.synchronizedMap“包”起来,否则等着被坑吧!

  4. 遍历? entrySet().iterator()永远比keySet()快! 记住,永远!

LinkedHashMap vs HashMap vs TreeMap?“选妃”指南

特性
LinkedHashMap
HashMap
TreeMap
迭代顺序
插入/访问顺序
无序
键自然顺序(A-Z)
时间复杂度
O(1) (大部分操作)
O(1) (平均)
O(log n)
内存消耗
较高 (多了链表)
中等
线程安全
使用场景
缓存、顺序访问
通用存储
范围查询、排序需求
  • LinkedHashMap
    : “秩序控”,需要记住操作顺序的场景。
  • HashMap
    : “糙汉子”,追求极致性能,不在乎顺序。
  • TreeMap
    : “强迫症”,必须按照key的顺序排列。

选哪个? 看你的需求! 别盲目追求“高大上”,适合自己的才是最好的!

LinkedHashMap:Java界的秩序控,是时候重新认识它了!

黑客/

原文始发于微信公众号(龙哥网络安全):LinkedHashMap:Java界的“秩序控”,是时候重新认识它了!

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月1日02:20:05
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   LinkedHashMap:Java界的秩序控,是时候重新认识它了!https://cn-sec.com/archives/4120061.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息