编写 equals 方法
395字约1分钟
2024-08-08
编写 equals
如何正确编写 equals()
方法?equals()
方法要求我们必须满足以下条件
自反性(
Reflexive
):对于非null
的x
来说,x.equals(x)
必须返回true
对称性(
Symmetric
):对于非null
的x
和y
来说,如果x.equals(y)
为true
,则y.equals(x)
也必须为true
传递性(
Transitive
):对于非null
的x
、y
和z
来说,如果x.equals(y)
为true
,y.equals(z)
也为true
,那么x.equals(z)
也必须为true
一致性(
Consistent
):对于非null
的x
和y
来说,只要x
和y
状态不变,则x.equals(y)
总是一致地返回true
或者false
对
null
的比较:即x.equals(null)
永远返回false
栗子
首先我们要定义"相等"的逻辑含义。对于 Person
类,如果 name
相等,并且 age
相等,我们就认为两个 Person
实例相等
public class Person {
public String name;
public int age;
}
对于引用字段比较,我们使用 equals()
,对于基本类型字段的比较,我们使用 ==
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
return this.name.equals(p.name) && this.age == p.age;
}
return false;
}
如果 this.name
为 null
,那么 equals()
方法会报错,继续改写如下
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
boolean nameEquals = false;
if (this.name == null && p.name == null) {
nameEquals = true;
}
if (this.name != null) {
nameEquals = this.name.equals(p.name);
}
return nameEquals && this.age == p.age;
}
return false;
}
如果 Person
有好几个引用类型的字段,上面的写法就太复杂了。要简化引用类型的比较,我们使用 Objects.equals()
静态方法
public boolean equals(Object o) {
if (o instanceof Person) {
Person p = (Person) o;
return Objects.equals(this.name, p.name) && this.age == p.age;
}
return false;
}