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