为什么这两个简单的对象不相等?

Lee*_*fin 5 java

我有一堂课:

public class School {

    private String name;
    private int id;
    private boolean isOpen;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public boolean isOpen() {
        return isOpen;
    }
    public void setOpen(boolean isOpen) {
        this.isOpen = isOpen;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了两个School实例,并比较了两个实例的相等性:

public static void main(String[] args) {
        //school1
        School school1 = new School();
        school1.setId(1);
        school1.setName("schoolOne");

        //school2
        School school2 = new School();
        school2.setId(1);
        school2.setName("schoolOne");

            //result is false , why?
        System.out.println("school1 == school2 ? " + school1.equals(school2));

    }
Run Code Online (Sandbox Code Playgroud)

即使我设置相同id,并nameschool1&school2实例,但school1.equals(school2)返回假的,为什么呢?

Mr.*_*irl 5

您必须覆盖该equals(Object)方法:

把它放在你的学校课堂上:

@Override
public boolean equals(Object other) {
    if (other == this) return true;
    if (other == null || !(other instanceof School)) return false;
    School school = (School) other;
    if (school.id != this.id) return false;
    if (!(school.name.equals(this.name))) return false;
    if (school.isOpen != this.isOpen) return false;
    if (!(school.hashCode().equals(this.hashCode()))) return false;
    return true;
}
Run Code Online (Sandbox Code Playgroud)

如果你要这样做,那么也可以覆盖这个hashCode()方法.

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (int) id;
    result = prime * result + (name != null ? name.hashCode() : 0);
    result = prime * result + (isOpen ? 0 : 1);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

附加信息

我相信这是压倒一切的最佳解释hashCode().

这个答案由dmeister发布,用于以下帖子:SO:Hash Code实现.

我一直在引用它,看起来这个函数在hashCode()为给定类生成方法时在Eclipse中使用.

对于几乎所有情况,在Josh Bloch的第8项"有效Java"中提出了合理的良好实现.最好的方法是在那里查找,因为作者解释了为什么这种方法是好的.

简短版本:

  1. 创建一个int结果并指定一个非零值.

  2. 对于在equals-Method中测试的每个字段,通过以下方式计算哈希码c:

    • 如果字段f是布尔值:calculate (f ? 0 : 1);
    • 如果字段f是字节,char,short或int:calculate (int)f;
    • 如果字段f是long:calculate (int)(f ^ (f >>> 32));
    • 如果字段f是浮点数:calculate Float.floatToIntBits(f);
    • 如果字段f是double:计算Double.doubleToLongBits(f)并处理返回值,就像每个long值一样;
    • 如果字段f是对象:使用hashCode()方法的结果或0if f == null;
    • 如果字段f是一个数组:将每个字段视为单独的元素,并以递归方式计算散列值,并按照下面的描述组合这些值.

  3. 将哈希值c与结果结合使用:

    result = 37 * result + c

  4. 返回结果

    这应该导致大多数使用情况的哈希值的适当分布.


Abi*_*san 1

您必须equals()有意义地重写该方法。equals()从类继承的默认方法Object检查两个引用是否引用内存中的同一对象。

Object 类的 equals 方法实现了对象上最具辨别力的可能等价关系;也就是说,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一对象(x == y 的值为 true)时,此方法才返回 true。