您的位置:

如何正确使用equals()方法进行Java对象比较

一、equals()方法的基本概念

在Java语言中,equals()方法是比较两个对象是否相等的方法。Object类中的默认实现是比较两个对象的引用是否相等。但是,对于我们自定义的类,需要覆盖equals()方法,根据实际需求进行比较。一般来说,比较的内容包含对象的属性,也可以考虑对象的指向等其他特殊情况。

Java语言规定:如果两个对象使用equals()方法比较相等,那么两个对象的hashCode()方法的返回值必须相等。

public boolean equals(Object obj) {
     if (obj == null) {
            return false;
     }
     if (!this.getClass().equals(obj.getClass())) {
            return false;
     }
     if (this == obj) {
            return true;
     }
     YourClass yourClass = (YourClass) obj;
     //比较两个对象是否相等
     return this.property1 == yourClass.property1 && this.property2.equals(yourClass.property2);
}

二、重写equals()方法的细节

1、先确认equals()方法的契约

在自定义类中覆盖equals()方法时,首先要沟通好同事之间使用这个方法的意义。例如,这里的"相等"是指什么?在定义相等的时候,往往也定义了相同的hashCode(),因此它们是相等的。在选择相等的概念时,需要注意的是如何使类在“集合框架”和其他Java库的所有客户端中表现良好。

2、遵守自反性、对称性、传递性、一致性和非空性

在实现equals()方法时,需要遵守以下五项规则:

  • 自反性:x.equals(x)始终返回true。
  • 对称性:x.equals(y)与y.equals(x)的结果应该相同,无论x、y的值如何。
  • 传递性:如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
  • 一致性:如果x.equals(y)返回true,那么多次调用x.equals(y)的结果应该始终为true或为false。
  • 非空性:x.equals(null)始终返回false。

3、使用getClass()检查属性的类型

在具有继承性的类中,如果没有getClass()方法,equals()方法可能会将派生类实例与其基类实例视为等同。这样可能会导致一些意想不到的结果。为了避免这种情况,可以使用getClass()方法将派生类实例与基类实例区分开来。如果两个对象的类不同,那么它们肯定不相等。

4、避免使用instanceof运算符

在某些情况下,可能会想通过使用instanceof运算符实现equals()方法。但这种方法会破坏equals()方法的对称性和传递性。如下所示:

public boolean equals(Object obj) {
    if (!(obj instanceof YourClass)) {
        return false;
    }
    YourClass yourClass = (YourClass) obj;
    //比较两个对象是否相等
    return this.property1 == yourClass.property1 && this.property2.equals(yourClass.property2);
}

在上述代码中,如果obj是YourSubClass的一个实例,那么在比较yourClass的属性时会导致ClassCastException异常。因此,尽量不要使用instanceof运算符进行类型判断。

三、使用Objects.equals()方法进行比较

Java SE 7 中添加了 Objects类,该类包含静态方法equals(),可以用来比较两个对象是否相等。引用为null的对象也被处理得非常好,因此它们不会抛出NullPointerException异常。例如:

public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final YourClass other = (YourClass) obj;
    if (!java.util.Objects.equals(this.property1, other.property1)) {
        return false;
    }
    if (!java.util.Objects.equals(this.property2, other.property2)) {
        return false;
    }
    return true;
}

四、总结

equals()方法是Java对象比较的方法,在自定义类中,需要重写equals()方法,实现根据实际需求进行比较。在重写equals()方法时,需要遵守equals()方法的契约,并使用Objects.equals()方法进行比较。