[英]General contract for object comparision : equals() and hashCode()
在equals方法的一般契约中有一点,它表示如果你已经定义了equals()
方法,那么你还应该定义hashCode()
方法。 如果o1.equals(o2)
那么这必须是o1.hashCode() == o2.hashCode()
。
所以我的问题是,如果我打破这份合同怎么办? 当o1.equals(o2)
但是o1.hashCode != o2.hashCode()
时,哪里可以带来失败?
它将导致基于散列的数据结构中的意外行为,例如: HashMap
, 读取HashTable的工作原理
HashMap / HashTable / HashSet / etc会根据hashCode
将你的对象放入几个桶中的一个桶中,然后检查该桶中已有的任何其他对象是否equal
。
因为这些类假定等于/ hashCode合约,所以它们不会检查与其他存储桶中的对象的相等性。 毕竟,另一个桶中的任何对象必须具有不同的hashCode,因此(通过契约)不能等于quesiton中的对象。 如果两个对象equal
但具有不同的哈希码,则它们最终会出现在不同的桶中,在这种情况下,HashMap / Table / Set /等将无法比较它们。
所以,你最终可能会得到一个包含两个相等的对象的Set - 它不应该这样做; 或者包含同一个键的两个值的Map(因为桶是按键); 或者您无法查找键的Map(因为查找检查哈希码和相等); 或任何数量的类似错误。
如果您违反合同,您的对象将无法使用基于散列的容器(以及使用hashCode()
并依赖其合同的任何其他内容)。
基本直觉如下:要查看两个对象是否相同,容器可以在两者上调用hashCode()
,并比较结果。 如果哈希码不同,则允许容器通过假设两个对象不相等而短路。
举一个具体的例子,如果o1.equals(o2)
但是o1.hashCode() != o2.hashCode()
,你可能会将两个对象都插入HashMap
(用于存储唯一对象)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.