小哎呀准备换工作了,重新捡起八股文也迎来了面试首挂,EmoEmo
那么,你真的知道重写equals方法为什么必须要重写hashCode方法吗?
hashCode与equals
我在学java的第一天就被灌输着这样一个知识点:
object1.equals(object2)可以用来比较两个对象内容,
而比较两个对象内容必须重写equals()和hashCode()
不重写hashCode方法,能成功判断两个对象是否相等吗?
比如:我们建一个Person类,有id属性和name属性,我们重写了equals方法,认为只要id一样,那么就是同一个人
public class Person {
private String name;
private Long id;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(id, person.id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public static void main(String[] args){
Person person1 = new Person();
person1.setId(111L);
person1.setName("一只小哎呀");
Person person2 = new Person();
person2.setId(111L);
person2.setName("小哎呀");
System.out.println(person1.equals(person2));
}
}
我们可以看到输出结果是true,也就是说我们不重写hashCode()是完全可以判断两个对象内容是否一致的。那为什么我们看到的答案都是要重写呢?
颠覆三观,所以为什么?
再比如,我们汇集了一波人做投票一类的,用到了HashSet做去重,那这时候会发生什么呢?
public static void main(String[] args){
Person person1 = new Person();
person1.setId(111L);
person1.setName("一只小哎呀");
Person person2 = new Person();
person2.setId(111L);
person2.setName("小哎呀");
System.out.println(person1.equals(person2));
HashSet<Person> set = new HashSet<>();
set.add(person1);
System.out.println(set.contains(person2));
set.add(person2);
System.out.println(set.size());
}
首先,因为我们重写了equals(),那么在对象比较时认为p1和p2是同一个人。
然后我们在hashSet中添加了p1,比较作为同一个人的p2是否在集合中,又发现不在;
在集合中添加p2,可以成功添加,且集合大小变成了2。
这样就很迷了,那p1和p2到底是不是同一个人?
写到这里答案就很清晰了,重写hashCode方法只是为了避免这种迷惑,这只是一个约定,同一个对象的hash值一定是相等的。