我的同事正在重写该equals()
方法。我的回答是,您是否也覆盖了该hashCode()
方法?他的回答是因为我们不会使用散列映射或散列集,如果我们覆盖应该并不重要hashCode()
。那是对的吗?
6 回答
是的,他实际上是正确的 - 但是,如果有一天您需要将对象放入基于哈希的集合中,则必须在任何地方添加哈希码,这可能会很烦人 + 那天您可能会错误地实现哈希码(即不一致with equals) 因为你错过了 equals 方法中的一些微妙之处......
考虑到大多数 IDE 都提供自动 equals/hashcode 生成功能,我认为没有理由不同时创建两者。
另一种看待它的方式是:当您覆盖父类的方法时,您应该遵循该父类定义的协定。在 Object 的情况下,equals 的 javadoc非常清楚:
请注意,每当重写该方法时,通常都需要重写 hashCode 方法,以维护 hashCode 方法的一般约定,即相等的对象必须具有相等的哈希码。
因此,除非您有真正的设计理由不覆盖哈希码,否则默认决定应该是遵循父类合同并覆盖两者都不覆盖或覆盖两者。
如果您覆盖equals()
,也请覆盖hashCode()
。即使您现在不使用hashCode()
,您或其他人也可能会使用它。
有关此主题的更多信息,请查看出色的SO 答案
这是一种代码气味。例如,如果您覆盖 hashCode 或 equals 而不覆盖另一个,Findbugs 会警告您。您应该覆盖两者,以使它们彼此一致(即 a.equals(b) => a.hashCode() == b.hashCode())。
现在稍加努力,以后可能会省去很多麻烦。
您必须在每个覆盖 equals 的类中覆盖 hashCode。不这样做将导致违反 Object.hashCode 的一般约定,这将阻止您的类与所有基于哈希的集合(包括 HashMap、HashSet 和 Hashtable)一起正常运行。
有效的 Java 条款 9:当你覆盖 equals 时,总是覆盖 hashCode。
如果您的课程是公共课程,那么您将无法控制您的课程在未来开发中的使用方式。如果不查看源代码(或通过反射),就无法知道这个类是否覆盖了 hasCode 方法,如果用户在任何基于散列的集合中使用它,用户会对结果感到惊讶。
一般的:
仅覆盖您想以自己的方式使用的那些方法以及受此覆盖影响的那些方法。
具体到您的问题:
从java文档,
请注意,每当重写 equals() 方法时,通常都需要重写 hashCode 方法,以维护 hashCode 方法的一般约定,即相等的对象必须具有相等的哈希码。
实际上假设您创建了两个不同的对象,而没有覆盖 equals 和 hashCode 方法。然后如果你调用 equals 方法 java 隐式调用 hashCode 方法然后检查哈希码的相等性。
重写 hashCode 方法足以检查两个对象的相等性。它对未来很有用。您可以在集合上使用此类。
否则,如果您只实现 equal 方法,它将仅解决两个对象的相等问题。