Java HashSet add()方法未调用重写的equals()方法

时间:2018-08-01 11:40:59

标签: java equals

我有此代码:

@Override
public boolean equals(Object obj) {

    System.out.println("equals called");

    if(this == obj) {
        System.out.println("THIS object is the same as OBJ");
        return true;
    }

    System.out.println("obj.getClass() is " + obj.getClass());
    System.out.println("this.getClass() is " + this.getClass());
    if ((obj == null) || (obj.getClass() != this.getClass())) {
        return false;
    }

    double objOrbitalPeriod = ((HeavenlyBody) obj).getOrbitalPeriod();
    return this.orbitalPeriod == objOrbitalPeriod;
}

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

在主代码中是:

private static Set<Planet> solarSystem = new HashSet<>();
public static void main(String[] args) {
    Planet planet = new Planet("Earth", 365.0);`
    solarSystem.add(planet);
    solarSystem.add(planet);
}

有人可以解释为什么它不打印任何东西吗?

我希望它可以打印: "equals called"

和(由于重复):"THIS object is the same as OBJ"

但是似乎发生了一些我无法理解的事情。

2 个答案:

答案 0 :(得分:5)

好吧,HashSet是使用HashMap实现的。在put中的HashMap的实现中,它使用适当的哈希值找到该节点,然后检查以下内容:

if (p.hash == hash &&

    ((k = p.key) == key || (key != null && key.equals(k))))

    e = p;

这意味着它首先检查对象身份,并且仅当对象不同时才调用equals方法。由于您的对象相同,因此不会调用equals方法。

Source of HashMap

答案 1 :(得分:0)

HashMapHashSet的内部实现)的源代码中,存在一个if条件,该条件表明如果两个键是相同的引用,则无需调用{{1 }}。

equals