我在很多地方读过,虽然equals在Java中覆盖hashCode方法,也应该覆盖方法,否则就是"违反合同".
但到目前为止,如果我只覆盖equals方法,而不是hashCode方法,我没有遇到任何问题.
合同是什么?当我违反合同时,为什么我没有遇到任何问题?如果我没有覆盖hashCode方法,在哪种情况下我会遇到问题?
fge*_*fge 151
你的问题是与地方元素的单一性根据双方计算的集合.equals()和.hashCode(),在一个实例键HashMap.
顾名思义,它依赖于哈希表,而哈希桶是对象的函数.hashCode().
如果你有两个对象.equals(),但是有不同的哈希码,你就输了!
这里合同的重要部分是:必须具有相同的对象.equals().hashCode().
这些都记录在javadoc中Object.和约书亚·布洛克说,你必须这样做在有效的Java.说够了.
Nun*_*ong 14
根据文档,hashCode的默认实现将返回一些对于每个对象不同的整数
尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数.(这通常通过将对象的内部地址转换为整数来实现,但
JavaTM编程语言不需要此实现技术.)
但是,有时您希望哈希码对于具有相同含义的不同对象是相同的.例如
Student s1 = new Student("John", 18);
Student s2 = new Student("John", 18);
s1.hashCode() != s2.hashCode(); // With the default implementation of hashCode
Run Code Online (Sandbox Code Playgroud)
如果在集合框架中使用散列数据结构(如HashTable,HashSet),则会出现此类问题.特别是对于像HashSet这样的集合,你最终会有重复元素并违反Set契约.
NIN*_*OOP 10
是的,它应该被覆盖.如果您认为需要覆盖equals(),则需要覆盖hashCode(),反之亦然.hashCode()的一般契约是:
每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象上的equals比较中使用的信息.从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致.
如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果.
如果两个对象根据equals(java.lang.Object)方法不相等,则不需要在两个对象中的每一个上调用hashCode方法必须生成不同的整数结果.但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能.
看看Hashtables, Hashmaps,HashSets等等。它们都将散列的密钥存储为它们的密钥。调用时get(Object key)会生成参数的哈希值并在给定的哈希值中查找。
当不覆盖hashCode()并且键的实例已更改时(例如一个根本无关紧要的简单字符串),hashCode()可能会导致同一对象有 2 个不同的哈希码,从而导致在map.get().
合约是:如果两个对象相等,则它们应该具有相同的哈希码,如果两个对象不相等,则它们可能具有或可能不具有相同的哈希码。
尝试使用您的对象作为 HashMap 中的键(在 joachim-sauer 评论后编辑),您将开始遇到麻烦。合同是一个指导方针,而不是强加给你的东西。
合同是,如果obj1.equals(obj2)那时obj1.hashCode() == obj2.hashCode(),它主要是出于性能原因,因为map主要使用hashCode方法来比较条目键.
在hashCode()其中说:
如果根据
equals(Object)方法两个对象相等,则hashCode在两个对象中的每一个上调用方法必须产生相同的整数结果.
(我强调).
如果你只是覆盖equals()而不是hashCode()你的班级违反了这个合同.
这也是在equals()方法的JavaDoc中说的:
请注意,通常需要在重写此
hashCode方法时覆盖该方法,以便维护该hashCode方法的常规协定,该协定声明相等的对象必须具有相等的哈希代码.
| 归档时间: |
|
| 查看次数: |
163759 次 |
| 最近记录: |