2

equals 方法的一般合同中有一点,它说如果你定义了equals()方法,那么你也应该定义hashCode()方法。如果o1.equals(o2)那么这是必须的o1.hashCode() == o2.hashCode()

所以我的问题是,如果我违反了这份合同怎么办?o1.equals(o2)但是哪里会带来失败的情况o1.hashCode != o2.hashCode()呢?

4

3 回答 3

5

它将导致基于哈希的数据结构中出现意外行为,例如:HashMap阅读 HashTable 的工作原理

于 2013-01-28T07:57:53.967 回答
5

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

因为这些类假定 equals/hashCode 契约,它们不会检查其他存储桶中的对象是否相等。毕竟,另一个桶中的任何对象都必须具有不同的 hashCode,因此(根据合同)不能等于问题中的对象。如果两个对象equal具有不同的哈希码,它们可能最终位于不同的桶中,在这种情况下,HashMap/Table/Set/etc 将没有机会比较它们。

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

于 2013-01-28T08:03:23.093 回答
4

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

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

举一个具体的例子, if o1.equals(o2)but o1.hashCode() != o2.hashCode(),您可能能够将两个对象都插入到 aHashMap中(这意味着存储唯一的对象)。

于 2013-01-28T07:58:15.130 回答