数组长度为8时不会转红黑树,因为树化需同时满足链表长度≥8且数组长度≥64,而8<64,此时优先扩容至16。

当HashMap的数组长度为8时,是否转红黑树并不取决于概率分布,而是由明确的确定性规则决定:只有当某个桶(bin)中链表长度达到8 且 数组长度不小于64时,才会触发链表转红黑树。数组长度为8本身是扩容过程中的一个中间状态,此时不可能触发树化。
树化的两个硬性条件缺一不可
HashMap在JDK 8+中采用“链表+红黑树”混合结构,但树化有严格前提:
- 桶内链表长度 ≥ 8:这是节点数量阈值,统计的是同一hash桶中通过拉链法连接的Node个数;
- table数组长度 ≥ 64:这是全局容量阈值,防止在小容量下因哈希碰撞频繁而过早树化,影响性能与内存开销。
因此,当数组长度仅为8时,即使某个桶中链表长度已达8甚至更多,也不会转为红黑树——因为第二个条件不满足。此时HashMap会优先选择扩容(resize),将数组长度翻倍至16,再重新散列所有元素。
数组长度为8时的实际行为:扩容优先于树化
数组长度为8通常出现在以下场景:
- 初始容量设为8(如
new HashMap(8)),尚未发生任何put操作; - 经过若干次put后,size达到阈值(8 × 负载因子0.75 = 6),下一次put触发扩容至16;
- 若发生严重哈希冲突(例如全部key的hash值对8取模结果相同),第7个元素插入时就会触发resize,而非树化。
换言之,在长度为8的表中,你永远观察不到红黑树节点——它根本不会被创建。
所谓“概率分布”为何不适用?
树化不是随机事件,没有概率模型可言:
- 哈希函数(如Object.hashCode())虽有统计意义上的均匀性,但具体碰撞情况依赖于key的类型和数据分布;
- 是否树化只取决于两个整数比较(链表长度≥8 ∧ table.length≥64),结果恒为true或false;
- 用户无法控制底层哈希扰动、扩容时机或树化判断逻辑,不存在可调节的“树化概率参数”。
试图计算“数组长为8时转红黑树的概率”,就像计算“水在100℃时结冰的概率”——它不符合物理条件,自然概率为0。
不复杂但容易忽略:树化是确定性策略,不是概率机制。关注哈希质量、合理设置初始容量、理解扩容边界,比研究不存在的概率更有实际价值。

















