​ 对象在不重写的情况下使用的是Object的equals和hashcode方法,默认的equals判断的是两个对象的引用是不是同一个对象,而hashcode也是基于对象地址生成的一个整数数值。

需要重写equals()的场景

​ 假设现在有很多学生对象,默认情况下,要判断多个学生对象是否相等,需要根据地址判断,如果对象地址相等则对象的实例数据一定是相同的。但现在我们规定,当学生的学号与性别相等时便认为学生对象是相等的,不一定需要对象地址完全相同,例如学生A的对象所在地址为100,学生A的个人信息为(id : 1,性别: 女, 年龄: 18, 电话:123456789),学生a对象所在地址为150,学生a的个人信息为(id : 1,性别: 女, 年龄: 18, 电话:789456123),这时如果不重写Object的equals方法,那么返回的一定是false,这时就需要重写equals()方法了。

public class Student{
private String id; // 学号
private String sex; // 性别
private String age; // 年龄
private String tel; // 电话号码

// 重写hashCode()方法
@Override
public int hashCode(){
int result = id.hashcode();
result = 17 * result + sex.hashCode();
return result;
}

@Override
public boolean equals(Object obj){
if(!(obj instanceof Student)){
return false;
}
Student stuObj = (Student) obj;
// 地址相等
if(this == stuObj){
return true;
}
//如果两个对象学号、性别相等,我们认为两个对象相等
if(stuObj.id.equals(this.id) && stuObj.sex.equals(this.sex)){
return true;
}
return false;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

public String getTel() {
return tel;
}

public void setTel(String tel) {
this.tel = tel;
}
}

需要重写hashCode()的场景

​ 接上面例子,即学生A和a在重写equals()方法后被认为是相等的

​ 将两个对象放入HashSet中

Set set = new HashSet();
set.add(s1);
set.add(s2);
System.out.println(set);

​ 如果没有重写hashcode方法,则会发现色图容器中有两个元素,并不会出现HashSet的去重操作。因为Set区别对象是否唯一的标准是两个对象的hashcode是否相等,然后再判断两个对象是否equals,因此需要重写hashCode()方法。

在HashMap中也是如此,Map是根据Key值的hashcode分配和获取对象保存数组下标的,然后再根据equals区分唯一值,所以在map和set中都需要重写Object的equals和hashCode方法