定义平等 Object类有两种方法可以推断出对象的身份:equals()和hashCode()。在 一般来说,如果你覆盖其中一种方法,你必须覆盖它们, 因为他们之间必须有重要的关系 保持。特别是,如果两个对象是相等的 equals()方法,它们必须具有相同的hashCode()值 (尽管如此) 相反的情况一般都不正确) 。[强调我加入]
我的问题涉及段落的后一部分“虽然反过来一般都不正确”。如何让一个类的两个不同实例具有相同的hashCode但不相等?
答案 0 :(得分:17)
简单来说,hashcode()是一个通过某个公式生成哈希的函数,因此可能存在一些冲突,两个不同的值可能会产生相同的哈希码。
如果我只是通过将mod乘以6来计算哈希码,那么两个不同的值可能具有相同的哈希码。
答案 1 :(得分:4)
您可以考虑hashes to be a bucket
..
因此,hashcode只是该Bucket的哈希值。任何数量的对象都可以拥有相同的哈希码,具体取决于用于计算哈希码的算法。
理想的算法是为不同的对象生成不同的哈希码。因此,理论上1 object
每bucket
..当然这是完美的情况,这可能是不可能的..
根据某些属性,存储桶当然可能包含多个对象。
答案 2 :(得分:4)
将hashcode视为可以减少检查相等性的工作量的东西。 如果两个对象相等,它们肯定会具有相同的哈希码。但是,如果两个对象具有相同的哈希码,则它们可能具有数学上高的相似性但仍然不相同。只是为了心态:想想在动物园里比较鸭子和大象。它们非常不同,并且将具有不同的抽象哈希码,因此您不必费心比较它们的腿,翅膀等,以检查它们是否相同。但是,如果您正在比较鸭子和天鹅,它们非常相似并且具有相同的抽象哈希码,所以现在您要比较每只动物的非常微小的特征以检查相等性。当你减少被比较的两个元素之间的极端性时,抽象哈希码变得越来越具体。比较鸭子和天鹅比鸭子和大象有更多的具体哈希码,比较不同品种的鸭子使哈希码更加具体,比较同一品种的两只鸭子的dna使哈希码更加具体。这个答案只是为了创建一个理解哈希码概念的思维模式。阅读本文后,您必须在此答案的上下文中模糊对哈希码一词的理解。
答案 3 :(得分:3)
我认为反过来实际上是
如果两个对象根据equals()方法不相等,则必须 有一个不同的hashCode()值
显然不成立,因为在一般情况下生成唯一哈希值是不可能的,因为您通常会尝试将一组值映射到一组较低基数的哈希码。
答案 4 :(得分:2)
我将使用示例解释它。假设字符串的hashCode()
基于字符串长度。在这种情况下,"foo"
和"bar"
的哈希码是相等的。但"foo"
本身并不等于"bar"
。
这是因为代码实现了一种公式:您可以确定每个对象的代码但不能从哈希代码中恢复对象。可以有多个具有相同哈希码的对象。
答案 5 :(得分:1)
您可以将hashCode()
实施定义为始终返回1
示例。这是完全有效的:不同的实例(不是equal
)可以具有相同的hashCode
。但是在HashMaps
,Sets
或其他类型的集合中查找这些对象的运行时性能将非常差(因为它们都在内部位于同一个存储桶中 - 查找性能从{{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但它们不相等。