hashmap链表转红黑树需同时满足:桶中节点数≥8且表容量≥64;否则先扩容。树化发生在put操作末尾的treeifybin中,该方法会校验容量条件。

当 HashMap 中某个桶(bucket)的链表长度达到 8,并且整个表的容量不小于 64 时,该链表会转为红黑树。
触发树化的两个必要条件
Java 8 的 HashMap 并不是一达到链表长度 8 就立刻树化,必须同时满足:
- 当前桶中链表节点数 ≥ 8(即 binCount >= TREEIFY_THRESHOLD(值为 8))
- 整个哈希表的容量(table.length)≥ 64(即 MIN_TREEIFY_CAPACITY(值为 64))
如果容量不足 64,会先进行扩容(resize),而不是树化。这是为了避免在小容量下过早树化,带来不必要的结构开销。
树化过程发生在 put 操作的尾部
在 putVal() 方法中,插入新节点后会检查链表长度:
- 遍历到链表末尾,计数器
binCount达到 8,说明已有 8 个节点(含新节点) - 此时调用
treeifyBin(tab, hash) -
treeifyBin先判断tab.length ,若成立则触发扩容;否则才真正调用 <code>treeify()将链表转为红黑树
红黑树结构与链表共存的细节
树化后,该桶的首节点类型从 Node 变为 TreeNode(继承自 Node,并扩展了红黑树所需字段:parent、left、right、red 等):
- 同一个桶中不会同时存在普通 Node 和 TreeNode;一旦树化,全部节点都转为 TreeNode
- TreeNode 仍保留 next 引用,可维持原有链表遍历逻辑(兼容性设计)
- 查找、插入、删除均走红黑树逻辑,时间复杂度从 O(n) 降至 O(log n)
退化回链表的时机
红黑树并非永久存在。当执行删除操作(remove)或 resize 后,若某树中节点数 ≤ 6,就会被转换回链表:
- 由
untreeify()完成,将所有 TreeNode 重新构造成普通 Node 链表 - 阈值设为 6(而非 8)是为了避免频繁树化/反树化的“抖动”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











