一文就带你搞懂✨为什么重写 equals 时必须重写 hashCode 方法?

文章目录

    • 整体结构图
    • ✨前景说明
    • ⭐为什么?有什么作用OR好处?
    • 实战演练
      • 没有重写hashcode()
      • 解决办法:重写hashcode()
    • 尾言


整体结构图

一文就带你搞懂✨为什么重写 equals 时必须重写 hashCode 方法?_第1张图片


✨前景说明

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

相信这个问题大部分小伙伴即使面试中没有被问到过,但肯定也听说过

那么这个问题到底是为什么?该怎么回答?今天我皮皮虾就来告诉各位小伙伴们

当然,如果对各位有那么亿点点小作用的话,那么期待大家的一键三连哦!



⭐为什么?有什么作用OR好处?

  1. 使用hashcode方法提前校验,可以避免每一次比对都调用equals方法,提高效率

    例如 HashSet是具有不可重复性的,每次往里面添加数据时,都会先计算该数据的 哈希值(即在哈希表中的存放位置),然后与set中已经存在的数据的 哈希值进行比较,如果都不同则添加在计算出的位置进行添加,如果相同则调用 equals方法进行判断,相同则不添加,不相同则散列到其他位置添加。

    因为不同对象出现 哈希值相同的概率是比较低的,所以重写了 hashcode方法可以减少 equals方法的调用,提高效率。

  2. 保证同一个对象,保证在equals相同的情况下hashcode值必定相同,如果重写了equals而未重写hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equal都是根据对象的特征进行重写的),但hashcode不相同,这样就不符合期望。


实战演练


没有重写hashcode()

public class test {


    public static void main(String[] args) {
        HashSet<User> users = new HashSet<>();
        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
//    public int hashCode() {
//        return Objects.hash(age, name);
//    }

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

    public String getName() {
        return name;
    }

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

在这里插入图片描述

为什么会这样?

前文已经提过:保证同一个对象,保证在equals相同的情况下hashcode值必定相同,因为自定义对象都是new出来的,所以地址不同,那么hashCode很大概率不同,所以不会出现哈希冲突,就不会调用equals去进行判断,那么这两个特征相同的对象(也就是我们觉得应该是一样的对象) 就成功加入到HashSet中去了。


解决办法:重写hashcode()

public class test {


    public static void main(String[] args) {
        HashSet<User> users = new HashSet<>();
        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
    public int hashCode() {
        return Objects.hash(age, name);
    }

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

    public String getName() {
        return name;
    }

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

可见对象被判定为重复,所以只有一份。

原理解析:因为重写了hashCode方法,那么对于特征相同的对象,那么他们的hash值是一样的,所以会出现hash冲突,出现了hash冲突就会去调用equals方法进行判断是否为同一个对象,因为重写了equals方法,那么这两个对象被判定为重复,所以HashSet里面只有一份。



尾言

我是 Code皮皮虾,未来的日子里会不断更新出对大家有益的博文,期待大家的关注!!!

创作不易,如果这篇博文对各位有帮助,希望各位小伙伴可以点赞和关注我哦,感谢支持,我们下次再见~~~

分享大纲

大厂面试题专栏


Java从入门到入坟学习路线目录索引


开源爬虫实例教程目录索引

更多精彩内容分享,请点击 Hello World (●’◡’●)


在这里插入图片描述

你可能感兴趣的:(大厂面试题,Java,java,大厂面试题,hashCode)