news 2026/9/10 22:13:17

【Java集合】深入浅出 Java HashMap:从链表到红黑树的“进化”之路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Java集合】深入浅出 Java HashMap:从链表到红黑树的“进化”之路

🍂枫言枫语:我是予枫,一名行走在 Java 后端与多模态 AI 交叉路口的研二学生。

“予一人以深耕,观万木之成枫。”

在这里,我记录从底层源码到算法前沿的每一次思考。希望能与你一起,在逻辑的丛林中寻找技术的微光。

在 Java 集合框架中,HashMap的底层实现在 JDK 1.8 迎来了一次重大革新:引入了红黑树。这一设计并非为了酷炫,而是为了解决哈希碰撞导致的性能退化问题。本文将结合底层源码,带你彻底搞懂 HashMap 是在什么条件下、如何进行树化的。


一、 核心源码常量定义

HashMap.java中,有三个关键常量决定了树化与退化的阈值:

/** * 1. 树化阈值:当桶中链表长度大于该值时,尝试转为红黑树 */ static final int TREEIFY_THRESHOLD = 8; /** * 2. 退化阈值:当扩容或删除节点导致树节点数小于该值时,转回链表 */ static final int UNTREEIFY_THRESHOLD = 6; /** * 3. 最小树化容量:只有当数组总容量大于该值时,才会真正进行树化 */ static final int MIN_TREEIFY_CAPACITY = 64;

二、 树化的“双重条件”深度逻辑

很多开发者只记得“链表长度 > 8”,但实际上源码中存在一个隐藏的判定逻辑

1. 触发入口:putVal方法

当我们在put一个元素时,如果发生碰撞且当前是链表结构,会进入以下逻辑:

// JDK 1.8 putVal 部分源码 for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); // 插入新节点(尾插法) if (binCount >= TREEIFY_THRESHOLD - 1) // 如果链表长度达到 8 treeifyBin(tab, hash); // 尝试树化 break; } // ... 忽略省略部分 }

2. 核心判定:treeifyBin方法

进入treeifyBin后,并不是直接转红黑树,它会先检查数组的长度:

final void treeifyBin(Node<K,V>[] tab, int hash) { int n, index; Node<K,V> e; // 【核心判定】 // 如果数组为空,或者数组长度 n < 64,则优先选择扩容而不是树化 if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY) resize(); else if ((e = tab[index = (n - 1) & hash]) != null) { // 只有数组长度 ≥ 64 且链表长度 > 8,才会执行真正的树化逻辑 // ... 将 Node 转换为 TreeNode 的过程 } }

三、 深度思考:背后的数学与工程考量

1. 为什么是 8?—— 泊松分布

根据HashMap源码注释,节点在哈希桶中的频率遵循泊松分布。在负载因子为 0.75 的情况下,链表长度达到 8 的概率极低,约为 0.00000006。

设计用意:正常情况下,我们几乎不会遇到树化。红黑树是为了应对那些哈希函数设计不佳,甚至遭受恶意哈希攻击导致大量碰撞的情况。

2. 为什么退化阈值是 6 而不是 7?

这是为了留出缓冲区。如果退化阈值也是 8,那么当一个桶的节点数在 7 和 8 之间反复变动时,会引起频繁的“树化 <-> 退化”转换。这会导致大量的TreeNodeNode对象的创建与销毁,严重影响性能。

3. 节点结构的巨大变化

树化不仅仅是逻辑变了,底层存储的对象类型也发生了质变:

  • 链表节点 (Node):包含hash,key,value,next

  • 树节点 (TreeNode):继承自LinkedHashMap.Entry,除了基本属性,还增加了parent,left,right,prev,red(红黑属性)。

空间代价TreeNode占用的内存空间大约是普通Node2 倍


四、 总结:HashMap 的进化准则

  1. 链表转红黑树:当前桶链表长度且数组总容量

  2. 红黑树转链表:在扩容或删除元素时,若树中节点数

  3. 核心哲学

    • 容量小、碰撞多:通过resize扩容来平摊碰撞。

    • 容量大、碰撞多:通过treeify提升查询效率(从 O(n) 降至 O(log n))。


💡 面试贴士

在面试中,如果面试官问:“HashMap 什么时候树化?”,完整的回答应该是:

“当链表长度超过 8 时,HashMap 会调用treeifyBin方法。但该方法内部会先判断数组容量,如果容量小于 64,会优先扩容;只有容量大于等于 64 且链表长度达到 8,才会正式转换为红黑树。”

关于作者: 💡予枫,某高校在读研究生,专注于 Java 后端开发与多模态情感计算。💬欢迎点赞、收藏、评论,你的反馈是我持续输出的最大动力!

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:

https://cloud.tencent.com/developer/support-plan?invite_code=9wrxwtlju1l

当前加入还有惊喜相送!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 7:31:39

连锁饮品店安全用电白皮书:能源设备智能管控与预警

1.背景随着消费升级浪潮的推进&#xff0c;连锁饮品行业迎来规模化扩张高峰&#xff0c;全国门店数量已突破50万家&#xff0c;密集分布于商圈、社区、交通枢纽等人员聚集区域。然而&#xff0c;在行业高速发展的背后&#xff0c;用电安全隐患正成为制约企业稳健运营的核心痛点…

作者头像 李华
网站建设 2026/9/9 13:29:15

吐血推荐专科生用的9款AI论文软件测评

吐血推荐专科生用的9款AI论文软件测评 2026年专科生必备的AI论文工具测评 随着人工智能技术的不断进步&#xff0c;越来越多的专科生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上琳琅满目的论文辅助软件&#xff0c;如何选择真正适合自己需求的产品成为一大难题…

作者头像 李华
网站建设 2026/9/4 20:09:47

大模型RAG中的语义理解vs语义检索:技术原理与实战应用指南

本文解析了RAG系统中语义理解与语义检索的区别与联系。语义理解是模型的基础能力(NLU阶段)&#xff0c;在智能体RAG中扮演核心角色&#xff0c;影响工具调用准确性&#xff1b;语义检索是检索技术&#xff0c;在传统RAG中是核心&#xff0c;依赖向量数据库实现相似度检索。两者…

作者头像 李华
网站建设 2026/9/7 1:38:14

值得收藏:DeepSeek V4即将发布:不卷推理,卷编程,国产AI能打!

DeepSeek将于2024年2月中旬发布新一代旗舰模型V4&#xff0c;主打强劲代码生成能力&#xff0c;在代码生成领域表现优于行业领先模型。V4采用全新mHC训练架构&#xff0c;解决了传统残差连接在超大规模模型中的不稳定问题&#xff0c;实现模型规模扩大而不增加芯片投入。DeepSe…

作者头像 李华