Java HashSet 的 add() 方法没有调用被覆盖的 equals() 方法

3

我有这段代码:

@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" 但似乎有些事情我无法理解。

3
我发现你的代码中使用了“HeavenlyBody”,而不是“Planet”。 - dehasi
尝试使用Set<HeavenlyBody>而不是Set<Planet>。 - HectorLector
“我有这段代码”属于哪个类? - azro
2个回答

5

好的,HashSet 是使用 HashMap 实现的。在 HashMapput 实现中,它会定位到具有适当哈希值的节点,然后检查以下内容:

if (p.hash == hash &&

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

    e = p;

这意味着它首先检查对象的身份,只有在对象不相同时才调用equals方法。由于您的对象是相同的,因此不会调用equals方法。 < p > HashMap源代码


0
在HashMap的源代码中(HashSet的内部实现),有一个if条件语句,它表明如果两个键是相同的引用,则无需调用equals方法。
...
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
    break;
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接