简体   繁体   English

对象比较的一般契约:equals()和hashCode()

[英]General contract for object comparision : equals() and hashCode()

There is a point in general contract of equals method, which says if You has defined equals() method then You should also define hashCode() method. 在equals方法的一般契约中有一点,它表示如果你已经定义了equals()方法,那么你还应该定义hashCode()方法。 And if o1.equals(o2) then this is must o1.hashCode() == o2.hashCode() . 如果o1.equals(o2)那么这必须是o1.hashCode() == o2.hashCode()

So my question is what if I break this contract? 所以我的问题是,如果我打破这份合同怎么办? Where can bring fails the situation when o1.equals(o2) but o1.hashCode != o2.hashCode() ? o1.equals(o2)但是o1.hashCode != o2.hashCode()时,哪里可以带来失败?

它将导致基于散列的数据结构中的意外行为,例如: HashMap读取HashTable的工作原理

HashMap/HashTable/HashSet/etc will put your object into one of several buckets based on its hashCode , and then check to see if any other objects already in that bucket are equal . HashMap / HashTable / HashSet / etc会根据hashCode将你的对象放入几个桶中的一个桶中,然后检查该桶中已有的任何其他对象是否equal

Because these classes assume the equals/hashCode contract, they won't check for equality against objects in other buckets. 因为这些类假定等于/ hashCode合约,所以它们不会检查与其他存储桶中的对象的相等性。 After all, any object in another bucket must have a different hashCode, and thus (by the contract) cannot be equal to the object in quesiton. 毕竟,另一个桶中的任何对象必须具有不同的hashCode,因此(通过契约)不能等于quesiton中的对象。 If two objects are equal but have different hash codes, they could end up in different buckets, in which case the HashMap/Table/Set/etc won't have a chance to compare them. 如果两个对象equal但具有不同的哈希码,则它们最终会出现在不同的桶中,在这种情况下,HashMap / Table / Set /等将无法比较它们。

So, you could end up with a Set that contains two objects which are equal -- which it's not supposed to do; 所以,你最终可能会得到一个包含两个相等的对象的Set - 它不应该这样做; or a Map that contains two values for the same one key (since the buckets are by key); 或者包含同一个键​​的两个值的Map(因为桶是按键); or a Map where you can't look up a key (since the lookup checks both the hash code and equality); 或者您无法查找键的Map(因为查找检查哈希码和相等); or any number of similar bugs. 或任何数量的类似错误。

If you break the contract, your objects won't work with hash-based containers (and anything else that uses hashCode() and relies on its contract). 如果您违反合同,您的对象将无法使用基于散列的容器(以及使用hashCode()并依赖其合同的任何其他内容)。

The basic intuition is as follows: to see whether two objects are the same, the container could call hashCode() on both, and compare the results. 基本直觉如下:要查看两个对象是否相同,容器可以在两者上调用hashCode() ,并比较结果。 If the hash codes are different, the container is allowed to short-circuit by assuming that the two objects are not equal. 如果哈希码不同,则允许容器通过假设两个对象不相等而短路。

To give a specific example, if o1.equals(o2) but o1.hashCode() != o2.hashCode() , you'll likely be able to insert both objects into a HashMap (which is meant to store unique objects). 举一个具体的例子,如果o1.equals(o2)但是o1.hashCode() != o2.hashCode() ,你可能会将两个对象都插入HashMap (用于存储唯一对象)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM