首先明确:
1.如果a.equals(b)为true,则a和b的hashCode值一定相等。
2.如果x和y是两个不同的对象,x.hashCode()与y.hashCode()基本不会相同。 --java核心技术第十一版卷一第179页
第二条简言之不同对象的hashCode值不相等
3.重写过后的equals是按照对象特征进行比较的,不是按照地址值
正文:
在set集合中要求不能出现重复元素。所以首先使用hashCode进行比较时可以更快的判断在集合中是否有要插入的元素。如果有相同的hashCode直接不插入,就不用进行equals比较(可以提升效率。)。具有不同的hashCode会直接插入。
那么为什么要重写hashCode呢?
因为要保证两个具有相同对象特征的对象可以不重复的存入set集合中。如果不重写hashCode,会导致hashCode不相同,所以两个具有相同对象特征的对象重复的存入了set集合中。
重写equals、未重写hashCode:
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
/* @Override
public int hashCode() {
return Objects.hash(name, age);
}*/
}
public class Student_test {
public static void main(String[] args) {
Student stu1 = new Student("晓梦",18);
Student stu2 = new Student("晓梦",18);
System.out.println(stu1.hashCode());
System.out.println(stu2.hashCode());
System.out.println(stu1.equals(stu2));
}
}
运行结果:
stu1.hashCode-->1967205423
stu2.hashCode-->42121758
stu1.equals(stu2)-->true
解析:
很显然stu1和stu2不是一个对象,但是在未重写hashCode,只使用重写后的equals情况下,存入set集合时判断stu1和stu2的hashCode不同,就会将具有相同元素特征的stu1和stu2存入set集合中,这显然是错误的。
重写后的hashCode会导致stu1和stu2是相同的,这时就不会存入具有相同元素特征的stu1和stu2。