对象比较的常规协定:equals()和hashCode()

时间:2013-01-28 07:54:07

标签: java

equals方法的一般契约中有一点,如果您已经定义了equals()方法,那么您还应该定义hashCode()方法。如果o1.equals(o2)那么必须o1.hashCode() == o2.hashCode()

所以我的问题是如果我违反这个合同怎么办?在o1.equals(o2)o1.hashCode != o2.hashCode()

的情况下,哪里可以带来失败的情况

3 个答案:

答案 0 :(得分:5)

这将导致基于散列的数据结构中出现意外行为,例如:HashMapRead how HashTable works

答案 1 :(得分:5)

HashMap / HashTable / HashSet / etc会根据其hashCode将您的对象放入多个存储桶中的一个存储桶中,然后检查该存储桶中是否存在其他任何对象equal

因为这些类假定等于/ hashCode合约,所以它们不会检查与其他存储桶中的对象的相等性。毕竟,另一个桶中的任何对象必须具有不同的hashCode,因此(通过契约)不能等于quesiton中的对象。如果两个对象是equal但具有不同的哈希码,则它们可能最终会出现在不同的桶中,在这种情况下,HashMap / Table / Set / etc将无法比较它们。

所以,你最终可能会得到一个包含两个相等的对象的Set - 它不应该这样做;或者包含同一个键​​的两个值的Map(因为桶是按键);或者您无法查找键的Map(因为查找检查哈希码和相等);或任何数量的类似错误。

答案 2 :(得分:4)

如果您违反合同,您的对象将无法使用基于散列的容器(以及使用hashCode()并依赖其合同的任何其他内容)。

基本直觉如下:要查看两个对象是否相同,容器可以在两者上调用hashCode(),并比较结果。如果哈希码不同,则允许容器通过假设两个对象不相等而短路。

举一个具体的例子,如果o1.equals(o2)只有o1.hashCode() != o2.hashCode(),您可能会将这两个对象插入HashMap(这意味着存储唯一< / em> objects)。