一、为什么要重写equals方法;
前面我们讲到,equals的特点:
- equals不能作为基本类型的比较;
- 所有类从Object类中继承equals方法,和 == 是一样的;
- String类和Date类等会重写equals方法,使得equals方法的作用是比较内容是否一样
所以说默认情况下,如果不重写的话,就是比较两个对象是否相等( return this == obj );但是有的时候我们不以他们是否指向相同的地址去判断他们是否相等,而根据对象的内容,或者说是否有相同的属性来判断他们是否相等。这个时候就需要重写equals方法了;
二、如何重写equals方法;
这里我重写了equals方法---->只要对象中的属性相同就相等;好好理解
package cn.zj.cq;
public class Demo03ReEquals extends Object {
public static void main(String[] args) {
Demo03Person demA = new Demo03Person("hh",34);
Demo03Person demB = new Demo03Person("hh",34);
Demo03Person demC = new Demo03Person("qq",34);
boolean as = demA.equals(demB); //这里我们传递过去的是demB的引用类型,而那边是Object,用到了多态
System.out.println(as);
}
}
package cn.zj.cq;
public class Demo03Person {
private String name ;
private int age;
//中间空的是构造器、get/set方法
//@Override
public boolean equals(Object obj){ //这里的Object就是Object;不是指其他的任意类型,就是 祖宗类,就是用到了多态!!!
//就是子类用到了父类的equals方法----> Object obj = demB----> new Demo03Person("qq",34);
//但是重写的Object类的equals方法不能访问到子类的属性,所以要向下转型;
Demo03Person dem = (Demo03Person)obj;
boolean b = this.name.equals(dem.name) && this.age == dem.age;
return b;
}
}
输出:
true
三、重写equals方法的时候为什么也要重写hashconde;
假设一、重写了equals方法,但是没有重写hashcode方法:
package cn.zj.cq;
import java.util.Objects;
public class Demo03Simp {
private String name;
public Demo03Simp() {
}
public Demo03Simp(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Demo03Simp that = (Demo03Simp) o;
return Objects.equals(name, that.name);
}
/* @Override
public int hashCode() {
return Objects.hash(name);
}*/
}
package cn.zj.cq;
public class Demo03Test {
public static void main(String[] args) {
Demo03Simp demA = new Demo03Simp("hehe");
Demo03Simp demB = new Demo03Simp("hehe");
System.out.println(demA.hashCode());
System.out.println(demB.hashCode());
System.out.println(demA.equals(demB));
}
}
输出:
973777424
304291381
true
从这个代码的输入我们可以看出:使用原有的hashcode方法---->根据对象的地址来生成hashcode值,这里的demA和demB肯定不等,所以生成不同的hash值;因为重写了equals方法,两个对象中的内容一样,所以得出的结果是true,但是根据hashcode的理解来说,对于两个相等的对象,其hashcode应该是一样的。所以这里产生矛盾了;
补充:
getclass()方法的作用:返回运行时的类;
package cn.zj.cq;
public class Demo {
public static void main(String[] args) {
Demo de = new Demo();
System.out.println(de.getClass());
System.out.println(de.getClass().getSimpleName());
}
}
输出:
class cn.zj.cq.Demo
Demo
instance of 作用:测试它左边的对象是否是它右边的类的实例;