Java中hashCode与equals方法的关系
我在很多地方读到过这样的话,在Java中重写Java中hashCode与equals方法的关系,java,Java,我在很多地方读到过这样的话,在Java中重写equals方法时,也应该重写hashCode方法,否则就是“违反合同” 但到目前为止,若我只重写equals方法,而不重写hashCode方法,那个么我并没有遇到任何问题 合同是什么?为什么我在违反合同时没有遇到任何问题?在这种情况下,如果我没有重写hashCode方法,我会面临一个问题吗?契约是:如果两个对象相等,那么它们应该具有相同的hashCode;如果两个对象不相等,那么它们可能具有或不具有相同的hashCode 尝试使用对象作为HashMa
equals
方法时,也应该重写hashCode
方法,否则就是“违反合同”
但到目前为止,若我只重写equals方法,而不重写hashCode方法,那个么我并没有遇到任何问题
合同是什么?为什么我在违反合同时没有遇到任何问题?在这种情况下,如果我没有重写hashCode方法,我会面临一个问题吗?契约是:如果两个对象相等,那么它们应该具有相同的hashCode;如果两个对象不相等,那么它们可能具有或不具有相同的hashCode
尝试使用对象作为HashMap中的键(根据joachim sauer的评论编辑),您将开始面临麻烦。契约是一种指导原则,而不是强加给你的东西。你将遇到的问题是,在集合中,元素的唯一性是根据
.equals()
和.hashCode()
计算的,例如HashMap
中的键
顾名思义,它依赖于哈希表,哈希桶是对象的.hashCode()
的函数
如果有两个对象是.equals()
,但具有不同的哈希代码,则会丢失
合同中重要的一部分是:属于.equals()
的对象必须具有相同的.hashCode()
这些都记录在。并且说你必须在家里做。说得够多了。是的,它应该被覆盖。如果您认为需要重写
equals()
,则需要重写hashCode()
,反之亦然。工程总承包合同为:
合同规定,如果
obj1.equals(obj2)
然后obj1.hashCode()==obj2.hashCode()
,这主要是出于性能原因,因为映射主要使用hashCode方法比较条目键。请参见
信中说:
如果根据equals(Object)
方法,两个对象相等,
然后必须对两个对象中的每个对象调用hashCode
方法
生成相同的整数结果
(我强调)
如果您只重写equals()
而不重写hashCode()
,则您的类违反了此约定
该方法的JavaDoc中也提到了这一点:
请注意,通常需要重写hashCode
方法
每当重写此方法时,以保持
hashCode
方法的契约,该方法声明必须有相等的对象
具有相等的散列码
看看
哈希表
,哈希映射
,哈希集
等等。它们都将散列键存储为它们的键。调用get(objectkey)
时,将生成参数的散列,并在给定的散列中查找
如果不覆盖
hashCode()
并且密钥的实例已更改(例如,一个简单的字符串根本不重要),则hashCode()
可能会导致同一对象有两个不同的hashCode,从而导致根据文档在map.get()
中找不到给定的密钥,hashCode的默认实现将返回每个对象不同的整数
只要合理可行,类对象定义的hashCode方法就可以
返回不同对象的不同整数。(这通常由
将对象的内部地址转换为整数,但此实现JavaTM编程语言不需要这种技术。) 但是,有时您希望具有相同含义的不同对象的哈希代码相同。比如说
Student s1 = new Student("John", 18);
Student s2 = new Student("John", 18);
s1.hashCode() != s2.hashCode(); // With the default implementation of hashCode
如果在集合框架中使用哈希数据结构,例如哈希表、哈希集,就会出现这种问题特别是对于HashSet之类的集合,您最终将拥有重复的元素并违反集合约定。“应该有”=>“必须有”,并且您应该提到“尝试将它们用作HashMap中的键”。如果obj1!=obj2然后obj1.hasCode()!=obj2.hashCode()@fge你说得对,hashCodes可能会冲突,我想这个“契约”的问题是没有任何东西能强制它。如果你弄坏了它,没有什么东西会马上坏。但是,如果您不遵守合同中您的部分,处理对象的其他代码可以自由“中断”。当你试图在
HashMap
.Short和“Nuff说”中使用这样的对象时,就会发生这种情况+1@fge我有一个困惑,为什么在HashMap中重写hashCode方法时需要重写equals方法。在任何情况下,如果对象的hashcode相等,hashmap将替换该值。@VikasVerma不,它不相等;首先,计算密钥的散列码,然后查询正确的bucket是否相等。如果不重写.equals(),可能会遇到两个具有相同哈希代码的对象不相等的情况,因为