【问题标题】:Why both hashCode() and equals() exist为什么 hashCode() 和 equals() 都存在
【发布时间】:2010-03-18 11:09:23
【问题描述】:

为什么java Object类有hashcode()和equals()两个方法?其中一个看起来是多余的,并且它渗透到了最底层的派生类?

【问题讨论】:

  • 您至少可以尝试阅读 API —— Object.hashcode() 的 Javadoc 明确表示“支持此方法是为了使用由 java.util.Hashtable 提供的哈希表。”

标签: java


【解决方案1】:

为什么你认为一个是多余的?他们说不同的话:

  • hashCode 是“给我一些方法来有效地查看两个对象是否可能相等”
  • equals 是“检查这个对象是否真的等于另一个”

你肯定需要两者 - although I don't believe they should really be in Object in the first place

您绝对需要哈希码才能使用哈希表执行有效的查找 - 而且您绝对需要进一步的相等性检查,因为哈希发生冲突(例如,可能的字符串远多于哈希码) .

【讨论】:

  • “我不相信他们真的应该在 Object 中。”你的意思是他们两个,还是只是 hashCode()? equals() 作为检查身份的最终方法(可能会以不同的方式命名以避免混淆)对我来说似乎是正确的地方。但是,equals() 作为一种检查相等性的虚拟方法似乎是在错误的地方。
  • @Martinho:两者都有。已经可以使用 == 检查引用标识...但是大多数类型实际上并没有“平等”的概念或基于其数据的合理散列 - 那么为什么要为所有对象宣传它们呢?当然,博客文章有更多详细信息:)
【解决方案2】:

首先,当您覆盖 equals() 时,您也必须覆盖 hashcode()。

没有这样做 将导致违反 Object.hashCode 的一般合同,这将 阻止您的课程与所有基于哈希的课程一起正常运行 集合,包括 HashMap、HashSet 和 Hashtable。

这是合同,从对象规范 [JavaSE6] 复制而来:

  • 在执行期间对同一对象多次调用它时 应用程序的化,hashCode 方法必须一致地返回 相同的整数,只要没有在 equals 比较中使用的信息 对象被修改。这个整数不需要与一个执行者保持一致 将一个应用程序转换为同一应用程序的另一个执行。
  • 如果两个对象根据 equals(Object) 方法相等,则调用- 对两个对象中的每一个对象执行 hashCode 方法必须产生相同的 整数结果。
  • 不要求如果两个对象根据equals(Object)方法不相等,则对两个对象分别调用hashCode方法 必须产生不同的整数结果。但是,程序员应该 意识到为不相等的对象产生不同的整数结果可能会提高 哈希表的性能。

【讨论】:

    【解决方案3】:

    基本思想是通过比较hashcode()s 可以快速检查两个对象是否可能相等。如果它们的哈希码相等,则对象可能相等(不一定,但这是一个很好的猜测)。然后使用equals() 进行更深入(也更昂贵)的检查。这对于加快所有类型的查找(从地图等)很重要。

    【讨论】:

    • 另外,因为 hashCode 是一个 int,它被用来作为一个随机访问的索引来加快查找速度。
    【解决方案4】:

    equals 用于比较对象,hashcode 用于从对象生成哈希值,然后由 java map 容器(Hashtable、Map 等)使用。

    通常的做法是一起覆盖它们(如果你覆盖哈希码,你需要覆盖equals,反之亦然)。

    【讨论】:

    • @Neeraj:hashCode 可能有冲突,即具有相同 hashCode 的对象并不总是相同。
    • 不适合。两个完全不同的对象可以具有相同的哈希码。想象一下,哈希码的最大值为Integer.MAX_VALUE,而理论上您可以创建无限数量的不同对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多