equals()本身是一个方法,并不是运算符,而且仅适用于引用数据类型
“==”在java的引用数据时使用时,比较的并不是具体的数值,而是地址值。此时并不能有效地比较引用数据类型中的具体数据,比较地址值对于引用数据类型而言没有用,就出现了equals()方法的重写
//此处需要注意的是,equals()方法的重写在编译器中是可以自动生成的
重写equals()的规定
1、对称性 x.equals(y)如果结果为true,那么y.equals(x)的返回结果应该也是true
2、自反性 x.equals(x)的结果应该也是true
3、传递性 如果x.equals(y)结果为true,y.equals(z)的结果也是true,那么z.equals(x)的结果也一定为true
4、一致性 无论x.equals(y)重复多少次,其结果应该不会发生改变
5、特殊情况,x.equals(null)应该返回的结果是flase
注:idea自动生成equals()方法,首先alt+insert,点击equals() and hashcode()选项进行自动生成
Chinese是一个用来举例的类,Person是他的父类
import java.util.Objects;
public class Person
{
private String name;
private int age = 1;
private boolean isMale;
public void eat()
{
System.out.println("人可以吃饭");
}
public void sleep()
{
System.out.println("人可以睡觉");
}
public void talk(String language)
{
System.out.println("人可以说话,使用的是:"+language);
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public boolean isMale() {
return isMale;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMale(boolean male) {
isMale = male;
}
};
class Chinese extends Person{
private String nation;
public void setNation(String nation) {
this.nation = nation;
}
public String getNation() {
return nation;
}
public void sleep()
{
System.out.println("中国人会睡觉");
}
public void eat()
{
System.out.println("中国人会睡觉");
}
public void talk(String language)
{
System.out.println("中国人可以说话,说的是"+ language);
}
@Override
public String toString() {
return "Chinese{" +
"nation='" + nation + '\'' +
'}';
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
//首先利用“==”可以判断二者是否指向的是同一个地址,或者是同一个对象
//如果是的话就可以直接返回true,节省步骤
if (o == null || getClass() != o.getClass()) return false;
//判断o是否时null,也就是上面注意事项五的提到的特殊情况
//二者如果父类不相同的的话,那么就绝不可能属性也相等
Chinese chinese = (Chinese) o;
//对o进行强制转化
return Objects.equals(nation, chinese.nation);
//针对特定属性,equals也会比较值,此时nation和chinese.nation都是属性值
//可以直接进行比较,且会返回准确的ture和flase
}
当存在多个属性的时候
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
isMale == person.isMale &&
Objects.equals(name, person.name);
//此时会用一个判断语句直接对几个属性返回的值进行判断
//其他的步骤和以上基本一致
}
不过当父类中已经有equals的重写,会影响子类equals的重写,比如在对Person类进行重写之后,再对Chinese类中的equals进行重写时,明显比之前重写的equals多了一步调用父类的equals
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
//此处会先判断,父类中继承的属性是否相等,所以直接调用父类中的equals
//根据返回结果再决定是否要进行比较
Chinese chinese = (Chinese) o;
return Objects.equals(nation, chinese.nation);
}
测试代码如下
public class Persontext
{
public static void main(String[] args) {
Chinese c1 = new Chinese();
Chinese c2 = new Chinese();
Chinese c3 = new Chinese();
c1.setName("tom");
c1.setNation("chinese");
c1.setAge(18);
c1.setMale(true);
c2.setName("tom");
c2.setNation("chinese");
c2.setAge(18);
c2.setMale(true);
c3.setName("Tom");
c3.setNation("USA");
c3.setAge(20);
c3.setMale(false);
System.out.println(c2.equals(c1));
System.out.println("******************************");
System.out.println(c2.equals(c3));
}
};
测试结果