在实施细则中 HashMap
,我可以阅读:
When using comparators on insertion, to keep a
* total ordering (or as close as is required here) across
* rebalancings, we compare classes and identityHashCodes as
* tie-breakers.
如果我有常数 hashCode
很好 equals
我的类没有实现 Comparable
它究竟将如何打破联系,树将如何建造?
我是说-水桶会变成一棵树 System.identityHashCode
打破平局。那我就给你打电话 containsKey
方法具有不同的示例(将具有相同的 hashCode
以及 a.equals(b) == true
)会有不同的结果 identityHashCode
那么,有没有可能树被错误的节点(从左到右)遍历而找不到键呢?
我是错过了什么还是这是正常的行为?
3条答案
按热度按时间sd2nnvve1#
不,您实际上是根据
System::identityHashCode
但是在这个bucket中,仍然有一些条目具有相同的hashcode(不是相同的,只是重要的部分)。所以当你寻找某样东西的时候,它有时必须同时考虑两者
left
以及right
,没办法,就这么简单。g2ieeal72#
铲斗将使用
identityHashCode
但查找只使用哈希码和compare()
电话(如果有)。这意味着它有时需要扫描节点的两个子树。查找逻辑如下所示
看到了吗http://hg.openjdk.java.net/jdk10/jdk10/jdk/file/ffa11326afd5/src/java.base/share/classes/java/util/hashmap.java#l1901 请注意
tieBreakOrder()
(负责比较的方法)identityHashCode
中的任何位置都不会调用sfind()
.myzjeezk3#
在引用的部分之前,我们已经解释了标识哈希码基绑定中断的动机:
hashmap.java,第212行:
因此,按标识哈希码排序提供了一个稳定的排序,以帮助实现拆分和
Iterator.remove()
操作(必须支持一致地继续遍历)。如本答案所述,它不用于查找操作,正如您在问题中所说的,两个相等的对象可能具有不同的标识码。对于具有相同哈希代码且未实现
Comparable
,没有办法遍历它们并通过equals
.