Object类中equals()方法的使用与重写
equals方法是Object超类中定义好的方法,其内部的默认比较方式为 == 比较
对于类对象之间的比较,比较其地址是否相同
Student s1 = new Student();
Student s2 = new Student();
//此时s1和s2分别指向堆空间中两个不同的对象 地址值不同
boolean b = s1.equals(s2);//比较地址 b1 = false
System.out.println(s1 == s2)// 比较地址 结果也为false
Student s3 = s2;//s3和s2指向同一个对象 地址值相同
boolean b2 = s3.equals(s2)//比较地址 b2 = true
System.out.println(s3 == s2)//比较地址 结果也为true
现实生活中,在使用equals时,可能更多地是希望比较两个对象的内容是否相同,这时就需要我们对Object中的equals方法进行重写
重写时有如下一些要求:
- 自反性:对于任何非空引用x,x.equals(x) 返回true
- 对称性: 对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)返回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
在重写equals()方法时,也有必要对hashCode()方法进行重写,尤其是当我们自定义一个类,想把该类的实例存储在集合中时
hashCode方法的常规约定为:值相同的对象必须有相同的hashCode,也就是equals()结果为相同,那么hashcode也要相同,equals()结果为不相同,那么hashcode也不相同
当我们使用equals方法比较说明对象相同,但hashCode不同时,就会出现两个hashcode值,比如在HashMap中,就会认为这是两个对象,因此会出现矛盾,说明equals方法和hashCode方法应该成对出现,当我们对equals方法进行重写时,也要对hashCode方法进行重写。
在工具中有快速生成两个方法,假设现在有一个学生Student类,其中有id 和 name两个特征。
@Override
public boolean equals(Object o){
//首先比较两个的地址值是否相同,如果相同,那内容也一定相同
if(this == o) return true;
//如果o为空值或者两个对象的类型是否相同,如果类型不同或者o为空值则内容一定不同
if(o == null || getClass() != o.getClass()) return false;
//将object类型的实例强转为Student类型
Student student = (Student)o;
//比较两个实例的id是否相同
if(id != student.id) return false;
//在比较name是否相同
return name != null ? name.equals(student.name ) : student.name == null;
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}