网上看了很多博客,说的都是云里雾里,所以在此我写一下个人认为比较清晰的理解。
首先我们有一个Student类,正常情况下我们要重写它的equals方法和hashCode方法。如下所示:
public class Student {
private String name;
private Integer age;
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
if (!name.equals(student.name)) return false;
return age.equals(student.age);
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age.hashCode();
return result;
}
}
由于name.hashCode()和age.hashCode()分别调用的是String和Integer的hashCode方法,所以只要两个Student实例的name和age相同,那他们的hashCode就肯定相同。
理清楚这点,我们就可以接下去看了。这里我们通过一个案例来理解为什么重写equals方法后必须重写hashCode方法?
首先有两个学生stu1和stu2,他们的name和age是相同的。此时有一个HashMap,要求先执行put(stu1,1),再执行put(stu2,2)。
首先正常情况下,由于这两个学生的name和age是相同的,所以equals相同,hashCode也相同,那结果会是stu2的值将stu1的值覆盖。
但是此时如果重写了equals方法却没有重写hashCode方法,那就会执行Object的hashCode方法,那么结果会是stu1和stu2的equals相同,hashCode不相同。那执行的结果stu2就不会将stu1覆盖,而是将自己也put进去。由于我们想的是相同的学生put进map里肯定是要覆盖的,这就与我们的想法相悖了,