繁体   English   中英

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

[英]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.

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