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

编程入门 行业动态 更新时间:2024-10-17 12:25:03

为什么<a href=https://www.elefans.com/category/jswz/34/1769232.html style=重写 equals() 就一定要重写 hashCode() 方法"/>

为什么重写 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 表的两个位置,造成大家约定俗成的规则,出现 一些不可预料的错误。

更多推荐

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

本文发布于:2023-12-07 09:55:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1670908.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:重写   方法   equals   hashCode

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!