【问题标题】:equals() without hashCode()没有 hashCode() 的 equals()
【发布时间】:2017-06-13 06:49:35
【问题描述】:

如果我只需要比较对象而不打算将对象放入任何基于哈希的容器中,我是否可以只实现 equals() 而不是 hashCode()?

似乎所有 Java 圣经都说这两个必须一起实现。 :(

我的担忧: - 如果我总是将 hashCode() 和 equals() 一起实现,将会有很多代码没有真正使用,并且没有单元测试覆盖。 (如果不使用,我不会对 hashCode() 进行单元测试) - 直到我将对象放入基于散列的容器中时,我才知道如何查找对象。只有到那时我才能确定使用哪种散列策略。

【问题讨论】:

  • 参考您的担忧:您可能想研究使用 github.com/jqno/equalsverifier 自动测试 equals/hashcode 合约
  • 使代码符合对象规范的一种简单方法是从 hashCode 返回相同的常量值。这并不理想(即,如果将其用作哈希,则会发生严重的冲突),但它永远不会“失败”,因为合同得到维护......

标签: java hash hashcode


【解决方案1】:

你可以,但你会违反equals 的一般合同,这会导致奇怪的错误。即使您认为自己没有使用散列码,您将对象传递给的任何外部代码也可能依赖于它们,即使它似乎不是基于散列的。如果你不打算给你的对象一个像样的哈希方法,至少让它抛出一个运行时异常。不过,给你的对象一个像样的 hashCode 几乎总是更好。

【讨论】:

    【解决方案2】:

    Oracle的教程answers这个

    hashCode() 方法

    根据定义,如果两个对象相等,则它们的哈希码也必须相等。如果重写 equals() 方法,就会改变两个对象相等的方式,并且 Object 的 hashCode() 实现不再有效。因此,如果你重写 equals() 方法,你也必须重写 hashCode() 方法。

    【讨论】:

      【解决方案3】:

      只要不是强制实现 hashCode,无论何时实现 equals,都必须同时实现 hashCode

      如果你不这样做,你最终会得到破碎的物体。为什么?对象的 hashCode 方法必须考虑与其 equals 方法相同的字段。通过覆盖 equals 方法,您将一些对象声明为与其他对象相等,但原始 hashCode 方法将所有对象视为不同。因此,您将拥有具有不同哈希码的相同对象。例如,在 HashMap 上调用 contains() 将返回 false,即使对象已被添加。

      【讨论】:

        【解决方案4】:

        我可以只实现equals()而不实现hashCode()吗?

        是的,你可以。因为它们只是来自父类Object的方法,所以实际上是你选择实现还是不实现(一起或个人)。

        All Java bibles say these two MUST be implemented together.

        如果您没有使用与hashcode(如您所说的基于哈希的容器)相关的任何东西,则不是MUST,但最好将它们一起实施以避免任何意外情况。

        【讨论】:

          【解决方案5】:

          是的,你可以,但是推荐吗?没有

          所有书籍都说,如果 equals 返回 true,则哈希码必须相同,事实就是如此。但是,最好为您自己的实例进一步指定它,就像使用 equals 一样。

          【讨论】:

            【解决方案6】:

            嗯,显然你可以,但你不打算使用散列这一事实并不是不实施它的充分理由。您使用的一些库可以使用散列。如果您想避免测试 equals 或 hashcode,您可以尝试自动生成这些方法(大多数 IDE 具有该功能),或使用项目 lombok (https://projectlombok.org)

            【讨论】:

              【解决方案7】:

              是的,你只能实现equals()方法而不实现hashcode()方法。

              但标准做法说你应该同时实现它们,对于相等的对象,哈希码应该是相同的。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-03-11
                • 1970-01-01
                • 2013-07-28
                相关资源
                最近更新 更多