【问题标题】:Why do we check hash if we are going to check equals anyways?如果我们要检查equals,为什么还要检查hash?
【发布时间】:2013-10-16 03:59:11
【问题描述】:

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

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

而不是简单

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

【问题讨论】:

    标签: java hash hashmap equals


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      如果两个对象相等,则哈希码必须相同。

      在这种情况下,换一种说法:“如果两个对象的哈希码不同,它们就不可能相等”

      因此,在这里我们只是通过首先比较 hashes 来缩短使用 equals() 的比较。

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

      另一方面,各种对象的equals() 方法可能涉及复杂的操作,当然与int 比较相比,它是一项昂贵的操作。所以,我们只做hash比较早退出。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

          但是说到Hashcode,我们应该注意

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

          • 如果两个对象具有相同的 hashcode ,这并不意味着它们
            必须相等

          • 还要注意,如果两个对象不相等,即使那样它们也可以有 相同的哈希码。

          你可以通过这个例子来理解。

          让我们考虑两个数字 10,40,哈希码逻辑是使用 %(Mod) 6 所以。例如 10 % 6 = 4 和 40 % 6 = 4

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

          但是,如果我将 Hashcode 逻辑更改为使用 % (Mod) 37 那么,例如 10 % 37 = 10 和 40 % 37 = 3

          现在有了这个哈希逻辑。 10 和 40 不同!

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

          【讨论】:

            【解决方案5】:

            在要比较的两个对象的哈希值总是已知的情况下,并且引用不同的对象通常具有不同的哈希值,比较它们通常比比较对象本身更快,有时甚至相当快,并且永远不会“慢得多”。例如,如果想比较两个 10,000 字符的字符串,除了最后几个字符之外它们是相同的,并且如果知道这两个字符串的哈希值,那么检查哈希值是否匹配会比检查足够多的字符便宜。每个字符串的第一个差异。

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

            【讨论】:

              猜你喜欢
              • 2020-07-28
              • 2020-01-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-10-30
              • 1970-01-01
              • 2011-03-09
              • 1970-01-01
              相关资源
              最近更新 更多