首先看下Java语言规范对equals方法的要求:
1:自反性,对于任何非空引用x,x.equals(x)都应该返回true。
2:对称性,对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
3:传递性,如果x.equals(y),y.equals(z)都返回true,那么,x.equals(z)返回true。
4:一致性,如果x和y引用的对象没有发生变化,那么无论调用多少次x.equals(y)都返回相同的结果。
5:对于任意非空引用x,x.equals(null)都应该返回false。
示例如下:
class Person
{
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
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;
}
}
对于引用类型,可借助Objects.equals来帮忙。
对于基本类型,直接使用 “==” 来判断相等性。
Objects.equals源码如下:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
可以发现满足提到的上面五个性质。
我们知道重写了equals方法时,就必须也要重写hashCode方法,至于为什么可以参考why在重写equals时还必须重写hashcode方法。
编写hashCode我们也可以借助Objects.hash来帮忙,如下:
class Person
{
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
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;
}
/**
* TODO: 覆写hashCode方法
*/
@Override
public int hashCode() {
return Objects.hash(firstName, lastName, age);
}
}
equals()
用到的用于比较的每一个字段,都必须在hashCode()
中用于计算;equals()
中没有使用到的字段,绝不可放在hashCode()
中计算。