Java HashMap treeify()为何比较同桶节点的哈希值?
关于HashMap treeify()中哈希值比较代码的疑问解答
1. 同桶元素确实可能拥有不同的内部哈希值
你之前的理解存在偏差:HashMap中同一桶的元素,原始哈希值(node.hash)可以完全不同。
HashMap计算桶下标的逻辑是 (table.length - 1) & node.hash,其中table.length是2的幂次。两个不同的哈希值,只要和(table.length-1)按位与的结果相同,就会被分配到同一个桶。举个实际例子:
- 假设桶数组长度为16(
table.length=16,则table.length-1=15=0b1111) - 哈希值
h1=1,计算下标:15 & 1 = 1 - 哈希值
h2=17,计算下标:15 & 17 = 1
这两个哈希值完全不同,但会被分到同一个桶里。
2. 哈希值比较的作用:作为红黑树排序的 fallback 依据
treeify()构建红黑树时,需要明确节点的排序规则,优先级如下:
- 首先尝试使用元素的
Comparable接口实现(如果元素实现了该接口),通过compareTo方法比较; - 如果元素未实现
Comparable,或者compareTo返回0(即无法通过自然排序区分节点),就会用哈希值比较来确定节点的插入方向; - 如果哈希值也相同,最后才会调用
tieBreakOrder()方法,通过对象的内存地址等信息做最终区分。
这段哈希值比较的代码,是红黑树排序逻辑的重要一环,保证在自然排序失效时,仍能提供稳定的排序依据,让红黑树可以正确完成插入和平衡操作。
3. 代码并非冗余
因为存在同桶元素哈希值不同的场景,而且即使哈希值相同,这段比较也不会产生副作用(最多进入后续的tieBreakOrder逻辑),所以它不是冗余代码。
内容的提问来源于stack exchange,提问作者yong _ta_Park
相关产品推荐
相关产品推荐

