您的位置 首页 java

「Java面试」为什么重写 equals() 就一定要重写 hashCode() 方法

问题分析

关于这个问题,首先需要深入了解一下equals这个方法。

这个 equals 方法是 String 这个类里面的实现。

从代码中可以看到,当调用equals比较两个对象的时候,会做两个操作

  1. == 号比较两个对象的内存地址,如果地址相同则返回true
  2. 否则,继续比较 字符串 的值,如果两个字符串的值完全相等,同样返回true
「Java面试」为什么重写 equals() 就一定要重写 hashCode() 方法

那equals和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方法,不重写hashCode方法。

就有可能导致 a.equals(b) 这个表达式成立,但是hashCode却不同。

那么这个只重写了 equals 方法的对象,在使用散列集合进行存储的时候就会出现问题。

因为散列结合是使用hashCode来计算key的存储位置,如果存储两个完全相同的对象,但是有不同的hashcode就会导致这两个 对象存储 在hash表的不同位置,当我们想根据这个对象去获取数据的时候,就会出现一个悖论,一个完全相同的对象会在存储在hash表的两个位置,造成大家约定俗成的规则,出现一些不可预料的错误。

总结

强调一遍,基础很重要,基础很重要。

不要觉得每天写CRUD能解决业务问题就很牛逼了,等你工作了7~8年以后会发现

对技术体系化的理解和技术底层原理的学习才是自己的核心竞争力。

喜欢我作品的同学记得转发、收藏、点赞!!

最新的资料文档已整理,包含如下↓(还在持续更新中!):
①100道最新大厂经典面试题解析资料文档!
②20万+字Java面试题解析和配套答案!
③从应届生到高级开发都适用的简历模板!
④从入门到精通的架构师学习路线图!
⑤还有各种技术流程图,路径图!

有需要的 Si 我 “Mic”拿!

文章来源:智云一二三科技

文章标题:「Java面试」为什么重写 equals() 就一定要重写 hashCode() 方法

文章地址:https://www.zhihuclub.com/170162.shtml

关于作者: 智云科技

热门文章

网站地图