1、为什么要重写equals方法,为什么重写了equals方法后,就必须重写hashcode方法,为什么要有hashcode方法,你能介绍一下hashcode方法吗?
equals方法默认是比较内存地址;为了实现内容比较,我们需要重写equals方法。
equals和hashcode之间有一个重要的契约,如果两个对象基于equals方法比较是相等的,那么它们的hashcode必须相同;如果比较不同,他们的hashcode不一定不同,但不同的对象应尽力返回不同的hashcode值,以提高哈希表的性能。
如果只重写了equals方法而没有重写hashcode方法,就会违反这个契约,导致哈希表如HashMap和HashSet工作不正常,例如两个内容相等的对象会被认为是不相等的,因为它们的哈希码不同。
hashcode方法用于计算对象的哈希码,这个哈希码用于在基于哈希的集合如HashSet、HashMap中快速查找对象,哈希码是一个整数,由对象的内容计算得到,哈希码的作用是减少比较操作的次数,提高查找效率。
public class test {
public static void main(String[] args) {
HashSet<User> users = new HashSet<>();//因为两个对象都是new出来的、所以地址不同哈希码也不同不会出现哈希冲突、不会调用equals判断、
// 因此两个特征相同的对象就都添加到hashset中去了、解决方法就是重写hashcode()方法、
users.add(new User(10,"111"));
users.add(new User(10,"111"));
for (User i:users) {
System.out.println(i);
}
}
}
class User {
int age;
String name;
public User(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "User{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o){
if(this==o)return true;
if(o==null||getClass()!=o.getClass()){return false;}
User user=(User) o;
return age== user.age&&Objects.equals(name,user.name);
}
@Override//重写了hashcode方法。
public int hashCode() {
return Objects.hash(age,name);
}
}
因为重写了hashcode方法,所以特征相同的对象他们的hash值是一样的,会引起哈希冲突,从而调用equals方法进行判断是否为同一对象、因为重写了equals方法,所以这两个对象被判定为重复,所以hashset里只有一份。