如果两个对象相等,则哈希码必须相同。那么为什么要办理登机手续HashMap
-
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {
而不是简单地
if ((k = e.key) == key || (key != null && key.equals(k)))) {
因为哈希检查很便宜,而equals()
方法调用可能很昂贵。如果哈希检查失败,我们无需费心equals()
检查返回 false,因此我们节省了时间。
如果两个对象相等,则哈希码必须相同。
在这种情况下,换一种说法:“如果两个对象的哈希码不同,它们就不可能相等”
equals()
所以,这里我们只是通过首先比较hash
es来缩短比较。
由于hash
is 类型int
,比较 2 int
s 并不是一项昂贵的操作(只需使用一条机器指令 - if_icmp<cond>
.
另一方面,equals()
针对各种对象的方法可能涉及复杂的操作,与int
比较相比,这当然是一项昂贵的操作。所以,我们只是hash
对较早的退出进行比较。
除了@MarounMaroun 所说的之外, hash 的另一个优点是它返回一个int
. 这使您可以将其用作数组的索引(这是哈希表的实现方式)。 equals
返回一个布尔值,因此不能以这种方式使用。
如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。
但是,当涉及到 Hashcode 时,我们应该注意
如果两个对象相等,它们将具有相同的哈希码
如果两个对象具有相同的 hashcode ,这并不意味着它们
必须相等
还要注意,如果两个对象不相等,即使那样它们也可以具有相同的哈希码。
你可以通过这个例子来理解。
让我们考虑两个数字 10,40,哈希码逻辑是使用 %(Mod) 6 计算的。前 10 % 6 = 4 和 40 % 6 = 4
虽然 10,40 不同但返回 Same HashCode。
但是,如果我将哈希码逻辑更改为使用 % (Mod) 37 那么,例如 10 % 37 = 10 和 40 % 37 = 3
现在有了这个哈希逻辑。10和40不一样!
因此哈希码基本上取决于您计算哈希的逻辑。
在要比较的两个对象的哈希值总是已知的情况下,并且引用不同的对象通常具有不同的哈希值,比较它们通常会比比较对象本身更快,有时会相当快,并且会永远不要“慢很多”。例如,如果想比较两个 10,000 个字符的字符串,除了最后几个字符之外它们是相同的,并且如果知道这两个字符串的哈希值,那么检查哈希值是否匹配会比检查足够多的字符更便宜每个字符串的第一个差异。
如果散列值未知,计算它们通常比直接比较对象要慢。如果它们有时是已知的,则检查它们是否已知并使用它们有时会有所帮助,有时则不会,这取决于对象在与散列值恰好不同的其他事物进行比较时涉及的频率,以及多长时间在这种情况下进行比较。另请注意,如果任意类型对象的集合需要支持与其他集合的直接比较以查看它们是否包含相同的内容,则计算和缓存它们包含的所有项目的哈希值可能对它们有利,以及组合散列,它结合了所有值的散列。