首页 > 其他分享 >为什么一个对象重写了equals必须也重写hashCode

为什么一个对象重写了equals必须也重写hashCode

时间:2023-04-02 20:22:18浏览次数:43  
标签:name age equals hashCode Person 重写

一言以蔽之:重写 equals 方法是为了比较对象的内容是否相等,重写 hashCode 方法是为了保证对象在哈希表等数据结构中的正确性。


 

1、在 Java 中,如果一个类重写了 equals 方法,则必须同时重写 hashCode 方法。这是因为在 Java 中,对象的 hashCode 值用于在哈希表(Hash Table)等数据结构中进行快速查找,而哈希表的实现原理是根据对象的 hashCode 值进行散列(Hash),所以如果两个对象的 equals 方法返回 true,则它们的 hashCode 值也必须相等,否则可能会导致哈希表的查询等操作出现错误结果。

以下是一个示例,演示了为什么需要同时重写 equalshashCode 方法:

public class Person {
    private String name;
    private int age;

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof Person)) return false;

        Person person = (Person) obj;

        if (age != person.age) return false;
        if (name != null ? !name.equals(person.name) : person.name != null) return false;

        return true;
    }
}

如果只重写了 equals 方法,而没有重写 hashCode 方法,则可能会导致哈希表中出现错误的结果:

Person p1 = new Person("Alice", 18);
Person p2 = new Person("Alice", 18);

Map<Person, String> map = new HashMap<>();
map.put(p1, "Hello");

// 此时尝试获取 p2 对应的值,由于没有重写 hashCode 方法,p1 和 p2 的 hashCode 值不相等
// 因此,虽然 p1 和 p2 的 equals 方法返回 true,但是从哈希表中获取 p2 对应的值时却会失败
String value = map.get(p2); // value 为 null

2、下面是一个重写了 hashCode 方法的示例代码:

public class Person {
    private String name;
    private int age;

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof Person)) return false;

        Person person = (Person) obj;

        if (age != person.age) return false;
        if (name != null ? !name.equals(person.name) : person.name != null) return false;

        return true;
    }

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

在上面的示例代码中,hashCode 方法重写的实现逻辑与 equals 方法的实现逻辑是一致的,都是比较 Person 对象的两个属性 nameage 是否相等,如果相等则返回相同的 hashCode 值。

需要注意的是,这里的 31 是一个质数,它的作用是为了避免哈希冲突,因为 31 的乘法运算比较快,而且相对来说能够更加均匀地散布哈希值,从而减少哈希冲突的发生。

重写了 hashCode 方法之后,就可以保证在哈希表等数据结构中,同一个对象的 hashCode 值不变,不同对象的 hashCode 值不同,从而能够正确地进行查找和比较操作。

 

标签:name,age,equals,hashCode,Person,重写
From: https://www.cnblogs.com/dk1024/p/17281176.html

相关文章

  • 修改头像,CreateModelMixin, RetrieveModelMixin, UpdateModelMixin内部的方法进行重写
    1.假设GET请求和POST请求,用的序列化类不一样,如何处理__ser.py 2.假设GET请求和POST请求,用的序列化类不一样,如何处理__views.py  3.假设GET请求和POST请求,用的序列化类不一样,如何处理总结  4.用户注册测试  5.查询用户名和用户头像  6.修改用户头像  7......
  • Java重写toString的意义
    Java重写toString的意义一.toString()方法toString()方法在Object类里定义的,其返回值类型为String类型,返回类名和它的引用地址.在进行String类与其他类型的连接操作时,自动调用toString()方法,demo如下:Datetime=newDate();System.out.println("time="+time);//相当于下......
  • Java 敞 HashCode
    HashCode算法长话短说,Java的Object.hashCode()实现算法,据get_next_hash所述,可选方案有多种,默认为5.>java-XX:+UnlockExperimentalVMOptions-XX:+PrintFlagsFin......
  • 为什么重写equals还要重写hashcode方法
    首先需要明白什么时哈希函数:哈希函数时一个特定的算法,将任意一个类型的对象转换成一串数字(无论对象的构造多么的复杂或者多么简单),转换完的数字就是这个对象的哈希值在Object......
  • C#中的Equals()和==
    C#中的类型分为值类型(如int、double等)和引用类型(用关键字class修饰的类型),下面分别针对这两种情况进行说明。值类型中的Equals()和==对于值类型来说,因为其只在栈上存在,所......
  • WPF重写Window标题栏
    <Windowx:Class="License.UI.DetailsInterface"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://sche......
  • Nginx 重写功能(location / rewrite)
    目录一、Nginx常见模块二、访问路由location2.1location常用正则表达式2.2location的分类2.3location常用的匹配规则2.4location优先级排列说明2.5location示例......
  • C#中重写(override)及覆盖(new)的区别详解
    1.重写和覆盖的定义1.1重写(override)的定义  在C#中,用override关键字来重写一个父类中的虚方法或抽象方法。override关键字用于指示编译器,我要用派生类中的一个方法......
  • Nginx 重写功能(location / rewrite)
     一、Nginx常见模块httphttp块是Nginx服务器配置中的重要部分,代理、缓存和日志定义等绝大多数的功能和第三方模块的配置都可以放在这模块中。作用包括:文件引入......
  • 方法重写
    方法重写方法重写只跟非静态方法有关重写:需要有继承关系,子类重写父类的方法!!方法名必须相同参数列表必须相同修饰符:范围可以扩大public>protected>default>priv......