1

为什么它没有到达“这里”的打印行?换句话说,为什么它不使用我覆盖的等于?提前致谢

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);
    }

}
4

2 回答 2

4

这是因为HashSet使用哈希码来测试对象是否已经在集合中,并且仅equals在发生冲突时使用。对象的默认哈希码是内部 id,因此两个对象相等并不意味着它们具有相同的哈希码。在这种情况下,显然没有碰撞,所以不需要HashSet调用equals

这就是为什么在覆盖hashCode时应该始终覆盖的原因equals。有关此主题的更多信息,请参阅本文。您应该编写一个hashCode方法,为equals. 例如:

public int hashCode() {
    return number;
}

的一般要求hashCode是满足的对象equals()应该返回相同的哈希码。请注意,没有要求未通过equals()测试的对象具有不同的哈希码。如果您返回一个常数(如 Jayamohan 建议的那样),则满足hashCode合同;但是,这将完全消除使用 a 的好处,HashSet您还不如使用简单的ArrayList.

于 2013-02-15T04:26:07.710 回答
1

在比较对象时,

  • equals如果hashCode不同,则不会调用方法
  • hashCode如果 (obj1 == obj2)将不会调用方法

因此,在您的情况下,由于您尚未覆盖 hashCode 方法,因此哈希码不同,因此不会调用 equals 。尝试如下覆盖 hashCode 方法,您的 equals 方法将被调用。

@Override
public int hashCode() {
    return 1;
}

Java 中的Object.equals API 状态如下

请注意,每当重写该方法时,通常都需要重写 hashCode 方法,以维护 hashCode 方法的一般约定,即相等的对象必须具有相等的哈希码。

因此,请记住在hashCode覆盖 equals 方法时进行覆盖。

于 2013-02-15T04:29:44.980 回答