【问题标题】:Equal Objects must have equal hashcodes?相等的对象必须具有相等的哈希码?
【发布时间】:2011-10-21 17:47:52
【问题描述】:

相等的对象必须具有相等的哈希码。根据我的理解,当我们打算在基于散列的数据结构中使用对象时,此声明是有效的。这是 java 文档中 hashcode 和 equals 方法的合同之一。我探索了这句话的原因并查看了implementation of hashtable,并在put方法中找到了下面的代码

if ((e.hash == hash) && e.key.equals(key)) 

所以我明白了,合同来自上述条件e.hash == hash。我进一步尝试探索为什么 java 在比较两个对象是否相等时检查哈希码。所以这是我的理解

  • 如果两个相等的对象具有相等的hascode,那么它们可以存储在同一个桶中,这对于仅在单个桶中查找来说会很好

  • 检查 hashcode 比实际调用 equals 方法要好,因为 hascode 方法比 equals 方法成本低,因为这里我们只需要比较 int 值,而在 equals 方法中可能涉及对象字段比较。所以 hashcode 方法提供了一个额外的过滤器。

如果以上两个原因都成立,请纠正我?

【问题讨论】:

  • 我不认为.equals() 用于比较哈希码或对象引用。
  • 当您使用不可变对象并且只计算一次哈希码时,这是一个很好的方法。哦,别忘了 HashTable 已被弃用。

标签: java collections hashcode


【解决方案1】:
  1. 正确,只是一个小修正 - 如果两个 不相等 对象具有相同的哈希码。
  2. 不完全是,最好先检查一下,作为不相等的过滤器,但是如果你想确保对象相等,你应该调用equals()

【讨论】:

  • 嗨 MByD,即使两个不相等的对象具有相同的哈希码,它们也会存储在同一个桶中。关于第二点,我同意在将键与相等方法进行比较之前使用 hashcode() 方法作为过滤器对于不相等的对象
【解决方案2】:

你错了。 equals 只返回一个布尔值(两个可能的值),并且需要另一个对象进行比较。 hashCode 返回一个 int(2^32 个可能的值),并且只需要调用该对象。

HashMap 尝试将其持有的所有对象分布到存储桶中。当在地图上调用put 时,它必须决定将哪个桶用于给定对象。因此,它使用hashCode(以桶数为模)来决定使用哪个桶。然后,一旦找到桶,它必须检查键是否已经在映射中。为此,它将存储桶中的每个对象与要放入地图的对象进行比较。为此,它使用equals。如果找不到对象,则将其添加到存储桶中。

不使用hashCode,因为它比equals 快。使用它是因为它允许在一组存储桶之间分配密钥。计算一次 hashCode 并将对象与(希望)0 进行比较,同一个桶中的一个或两个对象,将对象与已经存储在地图中的数千个对象进行比较,速度要快得多。

【讨论】:

  • 我误读了 OP 问题中的一个词,你把我引向了它。谢谢和 +1。
【解决方案3】:

“我进一步尝试解释为什么 java 在比较两个对象是否相等时检查哈希码”。 Put 方法不只是检查相等性,它试图首先缩小存储桶的范围,然后使用等于。这就是为什么我们需要在分桶集合的情况下将 HashCode 与 Equals 结合起来。

但是,如果您的唯一目的是检查两个对象之间的相等性,则永远不需要 hashcode 方法。

Obj1.equals(Obj2) 默认不会使用 hashcode 方法。

【讨论】:

    【解决方案4】:

    它是一种通用类型的合约,因此当我们将对象存储在基于散列的数据结构中时,我们应该始终一致地将相同的对象放入和取出哈希表。 它是我们创建的要遵守的合同,以便进入/放置过程顺利进行。

    【讨论】:

      猜你喜欢
      • 2022-10-16
      • 2013-04-30
      • 1970-01-01
      • 2011-07-23
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多