为什么它不到达“这里”的打印线?换句话说,为什么不使用我的重写等号? 提前致谢
import java.util.*;
class NumberClass extends Object{
private int number;
public NumberClass(int n){
number=n;
}
@Override
public boolean equals(Object other){
System.out.println("here");
return false;
}
@Override
public String toString(){
return number+"";
}
}
public class HelloWorld {
public static void main(String[] args) {
Set <NumberClass> set= new HashSet<NumberClass>();
set.add(new NumberClass(0));
set.add(new NumberClass(0));
System.out.println(set);
}
}
答案 0 :(得分:4)
这是因为HashSet
使用哈希码来测试对象是否已经在集合中,并且只有在发生冲突时才使用equals
。对象的默认哈希码是内部id,因为这两个对象相同并不意味着它们具有相同的哈希码。在这种情况下,显然没有发生冲突,因此HashSet
无需拨打equals
。
这就是您覆盖hashCode
时应始终覆盖equals
的原因。有关此主题的更多信息,请参阅this article。您应该编写一个hashCode
方法,为equals
的对象返回相等的哈希值。例如:
public int hashCode() {
return number;
}
hashCode
的一般要求是满足equals()
的对象应返回相同的哈希码。请注意,不要求equals()
测试失败的对象具有不同的哈希码。如果你返回一个常量(就像Jayamohan建议的那样),那就满足hashCode
契约;但是,这将完全消除使用HashSet
的好处,您也可以使用简单的ArrayList
。
答案 1 :(得分:1)
在比较对象时,
equals
方法将不 hashCode
方法将不调用if(obj1 == obj2)因此,在您的情况下,由于您没有覆盖hashCode方法,因此哈希代码不同,因此不会调用equals。尝试重写hashCode方法,如下所示,将调用equals方法。
@Override
public int hashCode() {
return 1;
}
Java中的Object.equals API说明如下
请注意,通常需要覆盖hashCode方法 每当重写此方法时,都要保持一般 hashCode方法的契约,它声明了相等的对象必须 有相同的哈希码。
所以请记住在覆盖equals方法时覆盖hashCode
。