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

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

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

我希望它应该打印: “等于调用”

和(因为它是重复的):“THIS object is the same as OBJ”

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

最佳答案

嗯,HashSet是使用HashMap实现的。并且在 HashMap 中的 put 的实现中,它找到具有适当散列的节点,然后检查:

if (p.hash == hash &&

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

    e = p;

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

Source of HashMap

关于Java HashSet add() 方法未调用重写的 equals() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51632372/

相关文章:

Java/Scala 指标 - Codahale - 集群/多节点和 Graphite Reporter

java - 为什么必须在子类方法的任何代码之前调用父类(super class)的方法版本?

java - 比较两棵树的等于方法

java - 嵌套 <嵌套 :equal> and <nested:write> in combination

java - 具有@EnableAutoConfiguration 注释的多个文件

java - Eclipse 中的错误标记未显示

java - 使用依赖注入(inject)容器时显式依赖

c - int 和 float 之间的关系比较是否可以在 C 中直接进行?

c++ - 为什么用于字符串比较的 == 运算符相对于任一字符串长度是线性时间(看起来)?

jquery - 事件后使用 Jquery 均衡高度