![](/img/trans.png)
[英]why should I override equals and hashcode method for following scnerio
[英]Why should I override hashCode() when I override equals() method?
好吧,我从许多地方和消息来源得知,每当我覆盖equals()方法时,我也需要覆盖hashCode()方法。 但请考虑以下代码
package test;
public class MyCustomObject {
int intVal1;
int intVal2;
public MyCustomObject(int val1, int val2){
intVal1 = val1;
intVal2 = val2;
}
public boolean equals(Object obj){
return (((MyCustomObject)obj).intVal1 == this.intVal1) &&
(((MyCustomObject)obj).intVal2 == this.intVal2);
}
public static void main(String a[]){
MyCustomObject m1 = new MyCustomObject(3,5);
MyCustomObject m2 = new MyCustomObject(3,5);
MyCustomObject m3 = new MyCustomObject(4,5);
System.out.println(m1.equals(m2));
System.out.println(m1.equals(m3));
}
}
这里输出是真的,完全按照我想要的方式错误,我根本不关心覆盖hashCode()方法。 这意味着hashCode()覆盖是一个选项而不是每个人都说的强制选项。
我想要第二次确认。
它适用于您,因为您的代码不使用需要hashCode()
API的任何功能(HashMap,HashTable) 。
但是,您不知道您的类(可能不是一次性写入)将在稍后使用其对象作为哈希键的代码中调用,在这种情况下,事情将受到影响。
hashCode的一般契约是:
每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象的equals比较中使用的信息。 从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致。
如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果 。
因为HashMap / Hashtable将首先通过hashCode()查找对象。
如果它们不相同,则hashmap将断言对象不相同并且返回不存在于地图中。
您之所以不需要@Override
,是因为它们与API的其余部分相互关联。
您会发现如果将m1
放入HashSet<MyCustomObject>
,则它不contains(m2)
。 这是不一致的行为 ,可能会导致很多错误和混乱。
Java库具有大量功能。 为了使它们适合你,你需要遵守规则,并确保equals
和hashCode
是一致的是最重要的一个。
大多数其他评论已经给你答案:你需要这样做,因为有一些集合(即:HashSet,HashMap)使用hashCode作为“索引”对象实例的优化,这些优化期望如果: a.equals(b)
==> a.hashCode() == b.hashCode()
(注意反转不成立)。
但作为附加信息,您可以执行此练习:
class Box {
private String value;
/* some boring setters and getters for value */
public int hashCode() { return value.hashCode(); }
public boolean equals(Object obj) {
if (obj != null && getClass().equals(obj.getClass()) {
return ((Box) obj).value.equals(value);
} else { return false; }
}
}
这样做:
Set<Box> s = new HashSet<Box>();
Box b = new Box();
b.setValue("hello");
s.add(b);
s.contains(b); // TRUE
b.setValue("other");
s.contains(b); // FALSE
s.iterator().next() == b // TRUE!!! b is in s but contains(b) returns false
你从这个例子中学到的是,使用可以改变的属性(可变)实现equals
或hashCode
是一个非常糟糕的主意。
在使用集合中的hashCode()值(即HashMap,HashSet等)搜索对象时,这一点非常重要。 每个对象都返回一个不同的hashCode()值,因此您必须覆盖此方法,以便根据对象的状态始终生成hashCode值,以帮助Collections算法在哈希表上定位值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.