• 为什么重写 equals() 就一定要重写 hashCode() 方法


    equals方法 

    这个 equals 方法是 String 这个类里面的实现。
    从代码中可以看到,当调用 equals 比较两个对象的时候,会做两个操作:
    1. 用==号比较两个对象的内存地址,如果地址相同则返回 true
    2. 否则,继续比较字符串的值,如果两个字符串的值完全相等,同样返回 true

    hashCode方法

    hashcode作用如下: 

    • 首先,Java 里面任何一个对象都有一个 native 的 hashCode()方法
    • 其次,这个方法在散列集合中会用到,比如 HashTable、HashMap 这些,当添加元素的时候,需要判断元素是否存在,而如果用 equals 效率太低,所以一般是直接用对象的 hashCode 的值进行取模运算

     对于散列集合:

    • 如果 table 中没有该 hashcode 值,它就可以直接存进去,不用再进行任何比较了;
    • 如果存在该 hashcode 值, 就调用它的 equals 方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用 equals 方法的次数就大大降低了 
    hashCode 的值默认是 JVM 使用随机数来生成的,两个不同的对象,可能生成的HashCode 会相同。这种情况在 Hash 表里面就是所谓的哈希冲突,通常会使用链表或者线性探测等方式来解决冲突问题。但是如果两个完全相同的对象,也就是内存地址指向同一个,那么他们的 hashCode
    一定是相同的。

    为什么重写 equals() 就一定要重写 hashCode() 方法

    在理论情况下,如果 x.equals(y)==true,如果没有重写 equals 方法,那么这两个对

    象的内存地址是同一个,意味着 hashCode 必然相等。

    但是如果我们只重写了 equals 方法,就有可能导致 hashCode 不相同。一旦出现这种情况,就导致这个类无法和所有集合类一起工作。所以,在实际开发中,约定俗成了一条规则,重写 equals 方法的同时也需要重写hashCode 方法。

    当我们只是重写了equals 方法,下面new两个对象,在我们定义下是相同的类

    但是对于没有重写的code方法根据对象的内存地址生成哈希码的。所以我们两个new的对象的code不同,放入哈希集合里面就会存入重复相同对象

    所以我们需要去重写hashcode方法

     

    总结

    如果只重写 equals 方法,不重写 hashCode 方法。就有可能导致 a.equals(b)这个表达式成立,但是 hashCode 却不同。那么这个只重写了 equals 方法的对象,在使用散列集合进行存储的时候就会出现问题。 因为散列结合是使用 hashCode 来计算 key 的存储位置,如果存储两个完全相同的对 象,但是有不同的 hashcode 就会导致这两个对象存储在 hash 表的不同位置,当我们想根据这个对象去获取数据的 时候,就会出现一个悖论 一个完全相同的对象会在存储在 hash 表的两个位置,造成大家约定俗成的规则,出现 一些不可预料的错误。
  • 相关阅读:
    Python 文件的读写操作
    BUUCTF·鸡藕椒盐味·WP
    Android 支持库迁移到AndroidX
    读书笔记:《量化投资实务》
    centos7.9下安装SVN服务
    如何运用 Python 异常处理,提高程序的高可用性?
    进程 线程 协程
    刷代码随想录有感(46):平衡二叉树
    小小装饰器大大用处
    如何建立自己的微信小程序,做一个微信小程序大概多少钱?
  • 原文地址:https://blog.csdn.net/qq_63431773/article/details/133937380