欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

为什么重写 equals 时必须重写 hashCode 方法?

程序员文章站 2024-03-25 22:50:52
...

因为不重写的话,set等不允许元素重复的散列表里会出现重复的元素。
因为散列表中先判断hashCode,相等后才会比较equals。

验证一下,首先我们先创建一个Person类,并重写equals方法(先不重写hashCode方法)

@AllArgsConstructor
public class Person {
    private String name;    
    private String sex;    
    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 String toString() {
        return "Person{" +
            "name='" + name + '\'' +
            ", sex=" + sex +
            '}';    
    }    
    
    @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(name, person.name) &&                
            Objects.equals(sex, person.sex);    
    }
}

然后new两个内容一样的Person实例,比较一下equals是否相等,再将其分别放入HashSet中,打印一下set中的内容。

    public static void main(String[] args) {
        Person person1 = new Person("Van Darkholme","♂");
        Person person2 = new Person("Van Darkholme","♂");

        System.out.println(person1.equals(person2));

        Set<Person> set = new HashSet<>();

        set.add(person1);
        set.add(person2);

        System.out.println(set.toString());
    }

我们知道HashSet中是不会拥有重复元素的。所以上面程序我们期望set中只有一个元素。

运行一下:

true
[Person{name='Van Darkholme', sex=♂}, Person{name='Van Darkholme', sex=♂}]

发现两个元素equals为true,说明两个元素相等,但是set中却出现了两个相同的元素。

看一下HashSet中add的源码,跟踪到HashMap的putVal方法。

为什么重写 equals 时必须重写 hashCode 方法?

我们可以看到方法中先比较元素的HashCode,如果相等再比较是否==或者equals是否为true,条件都成立才会元素替换。

我们通过打印的HashCode发现,两个实例的hashCode不同,当然也就不会进行equals的判断了。直接判断两个元素不同。

person1:966808741
person2:1908153060

相同的原理,如果重写equals不重写hashCode,HashMap中的key也会出现一样的问题。