为什么重写了equals()方法还需要重写hashCode()方法?|Java刷题打卡

本文正在参加「Java主题月 – Java 刷题打卡」,详情查看 活动链接

一、题目:为什么重写了equals()方法还需要重写hashCode()方法?

为什么我们在比较对象时,重写实体类中的equals时要重写hashCode方法,这次来一探究竟

equals()只是判断对象属性是否相同,hashCode()要判断二者地址是否相同。java中如果要判断两个对象是否相等,需要同时满足地址 + 属性都相同!

如果两个对象相同(即:用 equals() 比较返回true),那么它们的 hashCode 值一定要相同;
如果两个对象的 hashCode 相同,它们并不一定相同;
复制代码

二、代码演示

只重写 equals() 方法,不重写 hashcode() 方法
public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
    }
    @Override
    public boolean equals(Object obj) {
            if (this == obj)
                    return true;
            if (obj == null)
                    return false;
            if (getClass() != obj.getClass())
                    return false;
            Student other = (Student) obj;
            if (age != other.age)
                    return false;
            if (name == null) {
                    if (other.name != null)
                            return false;
            } else if (!name.equals(other.name))
                    return false;
            return true;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

复制代码
重写equals测试
Student stu1 = new Student("javazhang",26);
Student stu2 = new Student("javazhang",26);

System.out.println("两位同学是一个人吗?"+stu1.equals(stu2));   
System.out.println("stu1.hashCode() = "+stu1.hashCode());   
System.out.println("stu1.hashCode() = "+stu2.hashCode());


复制代码
重写equals测试
两位同学是一个人吗?true
stu1.hashCode() = 1013423070
stu1.hashCode() = 380936215
复制代码
重写 equals() 时,也重写了 hashCode() 方法
public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

复制代码
一起重写的输出
两位同学是一个人吗?true
stu1.hashCode() = -818588175
stu1.hashCode() = -818588175
复制代码

三、思考分析

重写了 equals() 不重写 hashcode() 方法

可能就会出现两个没有关系的对象 equals 相同,equals比较对象属性,但 hashcode 是不相同的。因为此时 Student 类的 hashcode() 方法就是 Object 默认的 hashcode()方 法,由于默认的 hashcode()方法是根据对象的内存地址经哈希算法得来的,两者在内存中的位置不同,new方法开辟新的内存空间,所以 stu1 != stu2,故两者的 hashcode 值不一定相等

根据 hashcode 的规则,两个对象相等其 hash 值一定要相等,不重写hashCode就会自相矛盾。用 hashcode 算法,所以即使字段属性相等,但是产生两个不同的 hashCode 值不等,显然不是我们理解的相等

重写了 equals() 也重写 hashcode() 方法

从 Student 类重写后的 hashcode() 方法中可以看出,重写后返回的新的 hash 值与 Student 的两个属性是有关,这样就确保了对象和对象地址之间的关联性,所以产生的hashCode相等,相对想也相同

四、总结

equals()只是判断对象属性是否相同

hashCode()要判断二者地址是否相同

java中如果要判断两个对象是否相同,需要同时满足地址 + 属性都相同!

如果两个对象相同(即:用 equals() 比较返回true),那么它们的 hashCode 值一定要相同;
如果两个对象的 hashCode 相同,它们并不一定相同;
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享