在ConcurrentHashMap中,为什么树的哈希值是负数,而链表的哈希值大于等于0
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Java的ConcurrentHashMap中,树化(将链表转换为红黑树)的条件之一是链表长度超过8。关于哈希值正负的问题,并不是直接由数据结构(链表或树)决定其正负,而是与ConcurrentHashMap内部实现细节有关。
在Java 8及之后版本的ConcurrentHashMap中,对于节点(Node)和树节点(TreeNode)的处理方式有所不同。具体到哈希值的表示上,这种差异体现在TreeNode类的设计上。TreeNode继承了Map.Entry<K,V>并实现了NavigableNode接口,它有一个额外的字段hash
,但这个字段并不直接用于判断是否转为树结构,而是为了在树结构中复用Entry的功能而设置的。
实际上,ConcurrentHashMap中的节点存储时,无论是链表还是树,它们的哈希值都是非负数。但是,在某些情况下,你可能看到的是TreeNode的父类ForwardingNode中的一个特殊用法,它使用负数来标记一种特殊状态,而不是用来表示树节点的哈希值。ForwardingNode是用来支持ConcurrentHashMap的扩容和分段锁机制的,当某个Segment正在进行resize操作时,它会创建一个ForwardingNode作为占位符,这个ForwardingNode的hash值被设置为-1,表示这是一个指向新数组的转发节点,而不是实际存储键值对的节点。
总结来说,树节点(TreeNode)的哈希值本身并不为负,任何节点(包括链表和树中的节点)的哈希值都应该是正常计算得到的非负整数。你所提到的“树的哈希值是负数”可能是对ConcurrentHashMap内部特殊节点(如ForwardingNode)用途的一种误解。在实际的数据结构转换逻辑中,决策依据主要是链表长度而非哈希值的正负。