Object 类中的 equals 方法用于检测一个对象是否等于另外一个对象
equals 方法
1. public boolean equals(Object obj) { 2. return (this == obj); 3.}
在Object 类中,equals 方法判断两个对象是否具有相同的引用。如果两个对象具有相同的引用,则返回true,否者返回false。
然而,对于多数类来说,这种判断并没有什么意义
例如:
在现实生活中,如果两个人身份证号相同的话,我们一般认为这两个人是同一个人。
如下,我定义一个Person 类,并声明两个对象person1 和person2,且这两个对象成员变量id赋值一样。如果按照我们想的,调用equals方法比较person1和person2返回值就应该是true,我们来看一下结果
class Person{ public String id; public Person(String id) { this.id = id; } } public class Test { public static void main(String[] args) { Person person1 = new Person("1234"); Person person2 = new Person("1234"); System.out.println(person1.equals(person2)); }
结果并不想我们想的那样,是false。为什么呢🤔?
那是因为Object类中的equals方式是比较两个对象的地址!如下图所示,虽然person1和person2中的成员变量值相同,但是这两个对象(引用)所指向的地址不一样,所以equals就判断为false
equals方法重写
为了能够实现我们想要的比较效果,我们可以在类中重写equals方法
class Person{ public String id; public Person(String id) { this.id = id; } @Override public boolean equals(Object obj){ Person tmp = (Person)obj;//向下转型,比较属性值 return this.id.equals(tmp.id); } } public class Test { public static void main(String[] args) { Person person1 = new Person("1234"); Person person2 = new Person("1234"); System.out.println(person1.equals(person2)); } }
我们在Person类中重写了equals方法,以成员id的值作为比较对象。这样结果就跟我们预期的一样了。(重写方法中,用equals方法比较String类型的数据,这个放在后面说)
equals方法重写规则
而重写方法也是有一定的规则的
自反性:对于任何非空引用 x, x.equals(x)应该返回 true。
对称性:对于任何引用 x 和 y ,当且仅当 y.equals(x)返回 true, x.equals(y) 也应该返回 true。
传递性:对于任何引用 x、y 和 z ,如果 x.equals(y) 返回 true,y.equals(z)返回true, x.equals(z) 也应该返回 true。
一致性:如果 x 和 y 引用的对象没有发生变化,反复调用 x.equals(y) 应该返回同样的结果。
对于任意非空引用x,x.equals(null)应该返回false。
就上述规则以外,我们还要注意参数是不是属于同一个类
例如一个变量person 属于Person类,一个变量dog属于Dog类,他们都有name成员。
如果他们俩的name值相等,我们能直接宣布person和dog是一个人吗?显然是不能的,因为人和狗就不是一个物种,同样变量 person 和 dog 就不是同一个类,不能直接拿来比较!
所以上述代码就可以修改为
@Override public boolean equals(Object obj){ //规则5 if(obj == null){ return false; } //规则1 自反性 if(this == obj){ return true; } if(!(obj instanceof Person)){ return false; } Person tmp = (Person)obj;//向下转型,比较属性值 return this.id.equals(tmp.id); }
检测类型,我们可以用 instanceof 关键字
equals方法比较String类型
当我们要比较字符串类型的内容时,我们不能用==来进行比较,应该用equals方法。
所有引用类型比较都要用equals方法,当我们比较String类型时,String内重写equals方法,比较的是字符串中的内容而不是地址。同样,相等返回true,不相等返回false。