【问题标题】:Consequences of different hashcodes but same equals for two java objects两个java对象的不同hashcode但相同equals的后果
【发布时间】:2023-03-29 18:25:01
【问题描述】:

我知道我们应该有相同的hashcodes incase equals 对于两个 java 对象是相同的,但只是想了解如果hashcodes 不一样但equals 返回true,会有什么后果关于 HashMap、HashSet 等集合。

它只会影响性能还是会影响那些集合类的行为/功能。

【问题讨论】:

  • 抓取时会错过bucket
  • 你需要维护 hashcode 和 equals 方法之间的契约以提高 hashmap 和 hashset 的性能

标签: java hash hashmap hashcode


【解决方案1】:

HashMap/HashSet 旨在帮助您在集合中找到目标对象。如果两个相等的对象有不同的hashcode,你不太可能在hash bucket中找到对象。

【讨论】:

    【解决方案2】:

    它会在获取期间丢失存储桶。 HashMap 旨在存储大量数据,在最佳情况下获取时间为 O(1)。为此,它存储针对哈希码(我们通常称为存储桶)标记的键/值。这称为散列技术。 因此,您将其存储在带有哈希码编号的哈希图中,例如 100,现在您尝试使用不同的哈希码(例如 200)获取对象(即查看不同的存储桶)。因此,即使您的对象在 hashmap 中,它也无法检索它,因为它会尝试在不同的存储桶(即 200)中查找。 这就是为什么我们应该有相同的哈希码,以防两个 java 对象的 equals 相同

    【讨论】:

      【解决方案3】:

      我们将对象称为o1o2,其中o1.equals(o2)o1.hashCode() != o2.hashCode()

      考虑以下几点:

      Map map = new HashMap();
      Set set = new HashSet();
      map.put(o1, "foo");
      set.add(o1);
      

      以下断言将失败

      Assert.assertTrue(map.containsKey(o2));
      Assert.assertTrue(set.contains(o2));
      

      【讨论】:

        【解决方案4】:

        如果两个对象相等,它们的哈希码将始终返回相同的值。

        请注意,通常需要在任何时候重写 hashCode 方法,以维护 hashCode 方法的一般约定,即相等的对象必须具有相等的哈希码。

        请阅读this

        【讨论】:

        • 你需要维护 hashcode 和 equals 方法之间的契约
        【解决方案5】:

        后果将是意想不到的行为。

        如果a.equals(b) == truea.hashCode()!=b.hashCode()set.add(a) 后跟set.contains(b) 很可能会返回false(假设setHashSet),即使根据equals 它应该返回@ 987654329@。 (最有可能但不确定的原因是两个不同的哈希码仍然有机会映射到HashSet/HashMap 的同一个桶,在这种情况下您仍然可以得到true)。

        【讨论】:

          【解决方案6】:

          它会破坏功能。如果您在哈希映射或哈希集中查找对象,它会使用哈希码来查找它。如果哈希码不一致,可能会找不到。

          哈希码最基本的要求是两个相等的对象必须有相同的哈希码。其他一切都是次要的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-23
            • 1970-01-01
            相关资源
            最近更新 更多