为什么java重写equals的时候要重写hashCode?
hashCode是不是重写需要看业务,可能有这种情况:比如我们仅仅通过对比object的部分属性来认定两者是否相等,而不对比其其他属性。
重写java object hashCode方法,是为了在一些算法中避免我们不想要的冲突。比如在HashMap,HashSet的使用中。
Student类
package test.equalshashcode;
public class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof Student) {
Student anotherStudent = (Student) anObject;
return id.equals(anotherStudent.id);
}
return false;
}
}
测试类
package test.equalshashcode;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Student student1 = new Student("STU001", "小明");
Student student2 = new Student("STU001", "小明");
// id相等,打印true
System.out.println(student1.equals(student2));
Map<Student, Integer> studentAgeMap = new HashMap<>();
studentAgeMap.put(student1, 20);
studentAgeMap.put(student2, 20);
// put方法会检查hashCode(key)是否相同,相同则覆盖value
// 此处用Object#hashCode方法,判定student1,student2不等
// 打印2
System.out.println(studentAgeMap.size());
// 根据与student1和student2相等的new Student("STU001", "小明")未获取到数据
// 打印null
System.out.println(studentAgeMap.get(new Student("STU001", "小明")));
// 总结
// 当我们new两个学生对象时,根据id是否相等重写了equals方法,但是两个学生对象的hashcode不等
// Map是根据hash(key)来判断key是否相等的
// 上面例子出现了悖论:
// equals相等的学生竟然能在Map的key中出现两次;
// 根据equals相等的new学生对象,未能从Map中获取数据
// 反证法得出结论:重写equals()必要时要重写hashCode()
}
}