让我们说我正在实现一个名为Car的类,其中包含2个成员变量int numDoors和String color。
在一个假设的案例中,我永远不会在散列表或散列图或任何需要散列的结构中使用这样的汽车,时间远古。
现在,为什么还需要覆盖hashCode和equals?
注意:我签出的所有答案都包括在hashtable / hashmap中使用。我已经尝试过广泛地得到这个答案,因此请求不要将其标记为重复。感谢
答案 0 :(得分:3)
如果两个对象根据
equals(Object)
方法相等,则在两个对象中的每一个上调用hashCode
方法必须产生相同的整数结果。
但是,它并不完全可以执行。
有些时候,您相信您不需要为您的对象定义和实施hashCode
,如果您不使用任何依赖于哈希来存储或引用它的结构,你是对的。
但是,您的对象可能会与第三方库接触,他们可能正在使用Map
或Set
来完成他们的工作,而且他们可以使用hashCode
或equals
来完成他们的工作。 d期望你遵循惯例。
由您决定不{{1}}与{{1}}一起实施 - 您当然不会被迫(虽然很多人会认为这是一个错误),但要注意因此,您的对象可能无法与第三方库一起使用。
答案 1 :(得分:0)
唯一无法以符合hashCode
和hashCode
合同的方式覆盖equals
方法的类型将是那些无法覆盖hashCode
的类型} [例如因为基类声明它为final
]。因此,几乎从来没有任何理由不合法地实施hashCode()
。即使一个类型不能保证不相等的实例不会自发地变得相等,该类型的作者仍然可以通过选择一个32大的hashCode()
值来合法地实现int
[例如} 8675309]并将hashCode()
作为@override int hashCode() { return 8675309; }
实施。这样做将允许所有基于散列表的集合类型正常工作。将很多这样的项存储到哈希表中会严重降低性能,但只有几个项的哈希表就可以正常工作并且通常表现得很好。相比之下,如果一个人不覆盖hashCode
,那么如果即使单项存储在其中,即使哈希表也可能无法正常工作。
顺便说一句,在某些情况下,即使不使用散列集合,实现hashCode
也可能有好处。例如,一些支持深度比较的不可变集合类型可能会对存储在其中的项目调用hashCode()
。如果集合很大,和/或对存储在其中的项目的比较操作很昂贵,则可以通过使用三步过程来增强测试两个集合的相等性(“它们包含相同项目”)的效率:
比较两个集合的聚合哈希码。如果他们不平等,没有理由再进一步了解。无论收藏的大小如何,都会产生即时结果。
比较所有项目的缓存哈希码。如果集合的内容匹配除了最后几个项目,并且如果项目之间的比较可能很昂贵(例如,项目是千字符串),这通常将避免需要比较除了其中一个项目之外的所有项目是否相等[注意如果除了其中一个项目之外的所有项目都匹配,并且它的哈希码不同,那么聚合哈希码就会有所不同,我们就不会这么做了。
如果所有哈希码都匹配,则在每个不比较引用相等的项目上调用equals
。
请注意,如果两个集合包含内容相同的不同项目,则需要进行比较以深入检查所有项目; hashCode
无法帮助处理此案件。另一方面,在比较事物的大多数情况下,它们并不相等,并且使用缓存的hashCode()
值可以在这些情况下促进数量级的加速。