如果我们要检查等于,我们为什么要检查哈希?

时间:2013-10-14 06:43:33

标签: java hash hashmap equals

如果两个对象相等,则哈希码必须相同。那么为什么HashMap中的任何检查都会 -

 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {

而不是简单地

if ((k = e.key) == key || (key != null && key.equals(k)))) {

5 个答案:

答案 0 :(得分:7)

因为哈希检查很便宜,equals()方法调用可能很昂贵。如果哈希检查失败,我们不需要打扰equals()检查以返回false,因此我们可以节省时间。

答案 1 :(得分:2)

  

如果两个对象相等,则hashcode必须相同。

在这种情况下,请采取另一种方式:“如果两个对象的哈希码不同,则它们不能相等”

因此,我们只是通过首先比较equals() es来使用hash简化比较。

由于hash的类型为int,因此比较2 int并不是一项昂贵的操作(只需使用一台机器指令 - if_icmp<cond>

另一方面,各种对象的equals()方法可能涉及复杂的操作,当然,与int比较相比,它使得操作成本高昂。因此,我们只需对早期退出进行hash比较。

答案 2 :(得分:1)

除了@MarounMaroun所说的,哈希的另一个优点是它返回int。这使您可以将其用作数组的索引(这是哈希表的实现方式)。 equals返回一个布尔值,因此不能以这种方式使用。

答案 3 :(得分:0)

如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须产生相同的整数结果。

然而,当谈到Hashcode时,我们应该知道

  • 如果两个对象相等,它们将具有相同的哈希码

  • 如果两个对象具有相同的哈希码,那并不意味着它们 必须是平等的

  • 另请注意,如果两个对象不相等,即使它们也可以 相同的哈希码。

您可以通过此示例了解。

  

让我们考虑使用两个数字10,40和Hashcode Logic   %(Mod)6所以。 ex 10%6 = 4和40%6 = 4

虽然10,40不同但返回Same HashCode。

  

但是如果我改变我的Hashcode逻辑使用%(Mod)37那么,前10%   37 = 10和40%37 = 3

现在有了这个哈希逻辑。 10&amp; 40是不同的!

因此,Hashcode基本上取决于你计算Hash的逻辑。

答案 4 :(得分:0)

在要比较的两个对象的哈希值总是已知的情况下,并且不是引用相同的对象通常会有不同的哈希值,比较它们通常比比较对象本身更快,有时候相当大,永远不会'慢'慢。例如,如果想要比较除了最后几个字符之外相同的两个10,000个字符的字符串,并且如果知道两个字符串的哈希值,则检查哈希值是否匹配将比检查足够的字符更便宜每个字符串找到第一个区别。

如果哈希值未知,则计算它们通常比直接比较对象慢。如果它们有时会被人知道,那么检查它们是否已知并使用它们有时会有所帮助,有时也不会有所帮助,这取决于对象与哈希值恰好不同的其他事物进行比较的频率以及持续时间这种情况下的比较需要。还要注意,如果任意类型对象的集合需要支持与其他集合的直接比较以查看它们是否包含相同的内容,那么它们可能有利于计算和缓存它们包含的所有项的哈希值,以及复合哈希,它结合了所有值的哈希值。如果有两个千字符串的大集合,除了最后一个字符串的最后几个字符之外可能有所不同,能够知道它们是不相等的而不必检查每个字符串的几乎每个字符都是一个很大的胜利。