12

我正在阅读以下文章引用的段落-Java 理论与实践:散列-有效且正确地定义 hashCode() 和 equals()

定义相等 Object 类有两种推断对象身份的方法:equals() 和 hashCode()。通常,如果您覆盖其中一种方法,则必须同时覆盖这两种方法,因为它们之间存在必须维护的重要关系。特别是,如果两个对象根据 equals() 方法相等,则它们必须具有相同的 hashCode() 值(尽管相反通常不正确)。[我补充的重点]

我的问题与该段的后半部分有关,“尽管通常情况相反”。一个类的两个不同实例如何具有相同的 hashCode 但不相等?

4

8 回答 8

17

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

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

于 2012-10-03T11:51:45.393 回答
5

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

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

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

一种理想的算法是为不同的对象生成不同的哈希码。所以,理想情况下,1 object每个bucket..当然这是完美的情况,这可能是不可能的..

一个桶当然可以包含几个对象,基于一些属性。

于 2012-10-03T11:54:35.713 回答
4

将哈希码视为只是减少检查相等性的工作量的东西。如果两个对象相等,它们肯定具有相同的哈希码。但是,如果两个对象具有相同的哈希码,它们可能在数学上具有很高的相似性,但仍然不相同。只是为了心态:想想把一只鸭子比作动物园里的一头大象。它们高度不同,并且会有不同的抽象哈希码,因此您不必费心比较它们的腿、翅膀等来检查它们是否相同。但是,如果您要比较鸭子和天鹅,它们非常相似并且具有相同的抽象哈希码,因此现在您只需比较每种动物的非常微小的特征来检查是否相等。随着您减少被比较的两个元素之间的极端性,抽象哈希码变得越来越具体。就像比较鸭子和天鹅比比较鸭子和大象有更具体的哈希码一样,比较不同品种的鸭子会使哈希码更加具体,比较同一品种的两只鸭子的 dna 会使哈希码更加具体。这个答案只是为了创造一种理解哈希码概念的心态。看完这篇,你一定模糊了对这个答案上下文中hashcode这个词的理解。

于 2016-12-27T02:54:44.050 回答
3

我认为反过来实际上是

如果根据 equals() 方法,两个对象不相等,则它们必须具有 A DIFFERENT hashCode() 值

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

于 2012-10-03T11:52:09.833 回答
2

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

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

于 2012-10-03T11:54:40.550 回答
1

您可以将您的hashCode()实现定义为始终返回1示例。这是完全有效的:不同的实例(不是equal)可以具有相同的hashCode. HashMaps但是在 或其他类型的集合中查找这些对象的运行时性能Sets会很差(因为它们在内部都位于同一个桶中 - 查找性能从O(1)到下降,O(n)因为您需要遍历同一个桶中的对象列表)。

还可以考虑看看HashMaps 在 Java 中是如何工作的

于 2012-10-03T11:54:44.520 回答
0

对象的哈希码通常比原始对象小得多。这是散列函数的目的之一。因此,您可以想象,如果您有 n 个不同的对象(例如一个类的所有排列),则不可能将它们编码为 m(其中 m < n)不同且更小(比原始对象)的唯一代码。

于 2012-10-03T11:55:43.777 回答
0

让我举个例子:

假设字符串的 HashCode 得到如下: hashCode = 每个字符 ASCII 码的总和(但我们知道,真正的 hash 更复杂)

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

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

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

于 2012-10-03T12:04:50.583 回答