split方法用于HashMap扩容时拆分红黑树:依据(e.hash & oldCap) == 0将节点分至低位链表(原索引)或高位链表(原索引 + oldCap),若子链表节点数≤6则退化为链表,否则重构为红黑树。

split 方法的作用是拆分红黑树节点
当 HashMap 扩容时,原数组长度从 oldCap 变为 2 × oldCap,所有元素需重新映射到新数组。对于红黑树节点(TreeNode),不能像普通链表那样简单遍历重哈希,而是调用 split 方法进行高效拆分。它的核心目标是:把一棵树按哈希值的高位 bit 分成两组——低位组留在原索引位置,高位组移到 原索引 + oldCap 的新位置。
拆分依据是 (e.hash & oldCap) == 0
因为容量始终是 2 的幂,比如 oldCap = 16(二进制 10000),那么 oldCap 的最高位就是那个唯一的 1。计算 e.hash & oldCap 实际上就是在检测 hash 值在该位是否为 0:
- 结果为 0 → 属于低位组(lo),新索引 = 原索引
- 结果非 0 → 属于高位组(hi),新索引 = 原索引 + oldCap
这个判断比重新计算 hash & (newCap - 1) 快得多,避免了全量 rehash,是 JDK 8 扩容优化的关键。
拆分过程分三步走
split 方法内部逻辑清晰:
立即学习“Java免费学习笔记(深入)”;
- 遍历当前红黑树的所有节点,用上述位运算分别归入 loHead/loTail 和 hiHead/hiTail 两个链表(保持插入顺序)
- 若某组节点数 ≤ 6,则直接转为普通链表(调用 untreeify);否则新建 TreeNode,将对应链表构造成新红黑树
- 最后把低位树挂到原索引位置,高位树挂到 原索引 + oldCap 位置
为什么树太小就退化成链表
红黑树维护成本高,节点太少时反而不如链表轻量。HashMap 规定:拆分后任一子树节点数 ≤ 6,就取消树化。这和 UNTREEIFY_THRESHOLD = 6 一致,也和链表转树的阈值 TREEIFY_THRESHOLD = 8 形成对称设计——留出缓冲区间,避免频繁树化/退化震荡。


















