问题:为什么根据自己的需求,重写equal函数的时候,必须重写hashcode函数?
回答:为了保证相等对象必须具有相同的哈希码
(哈希值是用来辅助判断对象是否相等,例如要将对象存储在HashSet中,首先要判断对象是否重复,即根据哈希值进行判断,如果哈希值不同,则说明对象不同,直接插入即可,若哈希值相同,再判断对象具体的属性是否相同,若不相同,则判断发生哈希冲突,通过哈希冲突处理再插入)
示例:某个学生类,包括学生姓名,学号,性别,家庭住址等信息,在判断学生是否相等时,我们设定如果学生的姓名,学号,性别相等,则这两个学生相等。
注意:针对引用数据类型,Object中提供的equal方法比较两个对象的地址是否相等,其子类可以对equal方法进行重写,例如String类中重写了equal方法,则String类中的equal方法比较的是两个字符串的内容是否相等。本例中,判断两个学生对象是否相等,需要判断两个学生的学号,姓名,性别是否相等。由于学号是int类型,直接判断基本数据类型是否相等即可;而姓名和性别是引用数据类型(String类),需要通过String类中重写的equal方法判断两个字符串是否相等。此时重写了学生类中的equal方法,也需要重写hashcode函数,保证通过equal方法判断的两个相等对象,具有相同的哈希值。则在重写hashcode函数时,需要考虑equal函数中比较的字段。
package com.csu.marden;
public class Person {
private int id;
private String name;
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sex == null) ? 0 : sex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
return true;
}
}
说明:
重写的hashcode要考虑equal函数中比较的字段,即int类型的id,String类型的name,sex。