两个具有相同哈希码但不相等的实例

时间:2012-10-03 11:49:03

标签: java equals hashcode

我正在读一篇名为“Java theory and practice: Hashing it out - Defining hashCode() and equals() effectively and correctly

的文章中引用的段落
  

定义平等   Object类有两种方法可以推断出对象的身份:equals()和hashCode()。在   一般来说,如果你覆盖其中一种方法,你必须覆盖它们,   因为他们之间必须有重要的关系   保持。特别是,如果两个对象是相等的   equals()方法,它们必须具有相同的hashCode()值 (尽管如此)   相反的情况一般都不正确) 。[强调我加入]

我的问题涉及段落的后一部分“虽然反过来一般都不正确”。如何让一个类的两个不同实例具有相同的hashCode但不相等?

8 个答案:

答案 0 :(得分:17)

简单来说,hashcode()是一个通过某个公式生成哈希的函数,因此可能存在一些冲突,两个不同的值可能会产生相同的哈希码。

如果我只是通过将mod乘以6来计算哈希码,那么两个不同的值可能具有相同的哈希码。

答案 1 :(得分:4)

您可以考虑hashes to be a bucket ..

  • 如果两个对象相等,它们将进入相同的存储桶(具有相同的哈希码)
  • 但是,如果两个对象进入相同的存储桶(具有相同的哈希码),那并不意味着它们必须相等
  • 另请注意,如果两个对象不相等,即使这样,它们也可以使用相同的哈希码。显然,这可以从以上两点推断出来。

因此,hashcode只是该Bucket的哈希值。任何数量的对象都可以拥有相同的哈希码,具体取决于用于计算哈希码的算法。

理想的算法是为不同的对象生成不同的哈希码。因此,理论上1 objectbucket ..当然这是完美的情况,这可能是不可能的..

根据某些属性,存储桶当然可能包含多个对象。

答案 2 :(得分:4)

将hashcode视为可以减少检查相等性的工作量的东西。 如果两个对象相等,它们肯定会具有相同的哈希码。但是,如果两个对象具有相同的哈希码,则它们可能具有数学上高的相似性但仍然不相同。只是为了心态:想想在动物园里比较鸭子和大象。它们非常不同,并且将具有不同的抽象哈希码,因此您不必费心比较它们的腿,翅膀等,以检查它们是否相同。但是,如果您正在比较鸭子和天鹅,它们非常相似并且具有相同的抽象哈希码,所以现在您要比较每只动物的非常微小的特征以检查相等性。当你减少被比较的两个元素之间的极端性时,抽象哈希码变得越来越具体。比较鸭子和天鹅比鸭子和大象有更多的具体哈希码,比较不同品种的鸭子使哈希码更加具体,比较同一品种的两只鸭子的dna使哈希码更加具体。这个答案只是为了创建一个理解哈希码概念的思维模式。阅读本文后,您必须在此答案的上下文中模糊对哈希码一词的理解。

答案 3 :(得分:3)

我认为反过来实际上是

  

如果两个对象根据equals()方法不相等,则必须   有一个不同的hashCode()值

显然不成立,因为在一般情况下生成唯一哈希值是不可能的,因为您通常会尝试将一组值映射到一组较低基数的哈希码。

答案 4 :(得分:2)

我将使用示例解释它。假设字符串的hashCode()基于字符串长度。在这种情况下,"foo""bar"的哈希码是相等的。但"foo"本身并不等于"bar"

这是因为代码实现了一种公式:您可以确定每个对象的代码但不能从哈希代码中恢复对象。可以有多个具有相同哈希码的对象。

答案 5 :(得分:1)

您可以将hashCode()实施定义为始终返回1示例。这是完全有效的:不同的实例(不是equal)可以具有相同的hashCode。但是在HashMapsSets或其他类型的集合中查找这些对象的运行时性能将非常差(因为它们都在内部位于同一个存储桶中 - 查找性能从{{1}降低}到O(1)因为你需要遍历同一个桶中的对象列表。)

另请考虑查看how HashMaps work in Java

答案 6 :(得分:0)

对象的哈希码通常比原始对象小得多。这是散列函数的一个目的。所以你可以想象,如果你有n个不同的对象(比如一个类的所有排列),就不​​可能在m(其中m< n)中编码它们,它们与原始对象的唯一代码不同。(/ p>

答案 7 :(得分:0)

让我举一个例子:

假设字符串的HashCode获得如下:hashCode =每个字符ASCII码的总和(但我们知道,实际哈希更复杂)

例如:“abc”的哈希码以这种形式计算:49 + 50 + 51 = 150

然后“acb”的哈希码等于:49 + 51 + 50 = 150

等等。正如您所看到的,有许多字符串具有hashcode = 150但它们不相等。