我一直在研究Java的HashMap,出现了一些问题。 再看
find
的HashMap
方法,写法如下:
else if ((q = pr.find(h, k, kc)) != null)
return q;
else
p = pl;
相比之下,
HashMap
中的其他方法(例如putTreeVal
或treeify
)使用tieBreakOrder
方法。我很好奇这两者之间的区别。
static int tieBreakOrder(Object a, Object b) {
int d;
if (a == null || b == null ||
(d = a.getClass().getName().
compareTo(b.getClass().getName())) == 0)
d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
-1 : 1);
return d;
}
在我看来,两者在遍历树节点方面都有共性——
find
方法直接遍历树的节点,而tieBreakOrder
似乎是在比较几个值。
所以,我是从原子操作的角度来思考的。我假设访问单个节点并比较原始数据值大约需要相同的操作时间。因此,我得出的结论是,实际上遍历节点的
find
方法可能比比较许多原始值的 tieBreakOrder
更快。
但是,我不确定我的假设是否正确,或者是否有其他原因让我可以更多地了解
find
和 tieBreakOrder
方法之间的区别?
非常感谢您帮助回答这个问题。谢谢!
扩展我的评论:如果你阅读代码中的评论,你会看到这个
tieBrakOrder()
:
打破平局实用程序,用于在 hashCode 相等且不可比较时对插入进行排序。我们不需要全序,只需要一致的插入规则来维持重新平衡之间的等效性。超出必要范围的平局打破会稍微简化测试。
这意味着在
putTreeVal()
或 treeify()
期间构建树时,需要打破平局以保持一致的顺序。
另一方面,
find()
仅使用树中已有的顺序,如果您查看该方法,您会看到首先尝试的其他一些操作:
treeify()
等类似的情况:我们需要另一种方法来找到正确的节点
正如你所看到的,这个逻辑中没有必要打破平局。搜索以确定性方式完成,即使重建树也会返回相同的结果 - 这就是打破平局所确保的。