equals方法在比较两个对象时,比较的是两个对象的地址值
Student student = new Student(2020102246,"张三");
Student student2 = new Student(2020102246,"张三");
System.out.println(student.equals(student2)); //结果为false
重写equals方法是为了达成我们想要的自定义的比较效果,使得不同地址值的对象的比较结果相同,例如只要学生对象的学号相同,我们就认为两个学生对象相同。
@Override
public boolean equals(Object obj) {
Student other = (Student) obj;
return this.studentId==other.studentId;
}
HashCode方法是用来计算对象的哈希码的,键值对对象存储在hash表的哪个位置就是由键的哈希码经过一系列的运算得出的。HashMap。HashSet等集合底层就是由哈希表实现。
重写Hashcode方法是为了使哈希码不根据键对象的地址值计算,而是根据键对象的属性值来计算。
使哈希值根据学生对象的学号计算。
@Override
public int hashCode() {
return Objects.hash(studentId);
}
需要说明的是,最好同时重写这两个方法是因为如果只重写了其中的一个方法,那么在使用哈希表时可能会出现重复存储元素的问题。我们需要使两个对象哈希码的比较结果和equals方法的比较结果相同。哈希表在存入对象时先使用键的哈希码计算要存入的下标位置,如果下标位置已经有元素再使用equals判断两个对象是否相等。HashSet,HashMap都是使用Hash表进行数据存储的集合。
如果只重写了其中一个方法,那么在哈希表中可能会重复存储相同的对象(属性值相同,地址值不同)。例如只重写了hashCode方法,因为存入哈希表的下标是根据哈希码计算,那么属性值相同的两个对象计算出来的下标相同,但是因为没有重写equals方法,那么经过equals方法的比较结果为false,就判定为这两个对象不同,就会在该下标处接上一个相同的元素,形成一条链表。