Java面试题(1) 为什么重写 equals() 就一定要重写 hashCode() 方法?

news2024/9/21 2:42:32

目录

    • 一、问题分析
      • 1.equals() 的实现
      • 2.equals() 和 hashCode() 的关系
      • 3.存在的问题
    • 二、完整回答

一、问题分析

1.equals() 的实现

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

String 类 equals() 源码如下:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

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

  1. 使用 == 号去比较两个对象的的内存地址,如果地址相同则返回 true。
  2. 如果第1个操作没有满足,就会继续去比较这两个字符串的值。如果这两个字符串的值完全相同,同样返回 true。

那 equals() 和 hashCode() 有什么关系呢?

2.equals() 和 hashCode() 的关系

首先,Java 里面任何一个对象都有一个 native 的 hashCode() 方法。

其次,这个 hashCode() 方法在散列集合中会用到,比如:HashTable、HashMap 这样一些集合类。当往这样一些集合类添加元素的时候,需要判断元素是否存在。而如果直接使用 equals() 的话效率太低,所以一般是直接使用对象的 hashCode 的值进行取模运算。如果 table 里面没有这个对象的 hashCode 对应的值,那么它就可以把这个对象直接存进去。不用再进行任何比较

而如果存在的话,就需要调用它的 equals() 方法,与新元素进行比较。相同的话就直接覆盖,不相同就散列到其他的地址

所以这里面存在一个冲突解决的问题。这样一来,实际调用 equals() 方法的次数就大大降低了

hashCode 的值,默认是 JVM 使用随机数来生成的,两个不同的对象可能生成的 hashCode 会相同。那么这种情况下,在 Hash 表里面体现就是所谓的 哈希冲突 。通常会使用链表线性探测等方式来去解决这个冲突的问题。但是如果两个完全相同的对象,也就是内存地址指向同一个,那么他们的 hashCode 一定是相同的

了解了 equals() 方法和 hashCode() 方法的关系以后,我们再来分析一下这个面试题。

3.存在的问题

在理论情况下,假设 x.equals(y) == true,如果没有重写 equals() 方法,那么这两个对象的内存地址一定是同一个,意味着 hashCode 必然是相等的。

但是如果我们之重写了 equals() 方法,就有可能导致 hashCode 不相同。一旦出现这样的情况,就会导致这个类无法和所有集合类一起工作

所以在实际开发过程中,约定俗成的一条规则:

重写 equals() 方法的同时,也需要重写 hashCode() 方法。

下面我们来看一下关于这个问题的完整的回答:

二、完整回答

  • 如果只重写 equals() 方法,不重写 hashCode() 方法,就可能会导致 a.equals(b) 这样一个表达式成立,但是 hashCode 却不同。

  • 那么这个只重写了 equals() 方法的对象,在使用散列集合进行存储的时候就会出现问题。因为散列集合是使用 hashCode 来计算 key 的存储位置,如果存储两个完全相同的对象,但是有不同的 hashCode,就会导致这两个对象存储在 hash 表的不同位置。当我们想要去根据这个对象去获取数据的时候,真实拿到的数据和我们实际想要的数据就可能存在偏差,从而导致系统出现不可预知的错误。

整理完毕,完结撒花~ 🌻

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/902552.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux —— 进程间通信(System V)

目录 一,共享内存 申请共享内存 shmget 控制共享内存 shmctl 关联共享内存 shmat / 去联共享内存 shmdt 二,消息队列 创建或打开消息队列 msgget 发送消息 msgsnd / 接收消息 msgrcv 控制消息 msgctl 三,信号量 创建或打开信号量 s…

java八股文面试[java基础]——面相对象特点

三大特点: 封装 继承 多态 面试题:java如何实现多继承(除了使用接口之外) 实现多继承有三个方法: 多层继承内部类接口 知识来源: 【基础】面向对象_哔哩哔哩_bilibili 【2023年面试】Java面向对象有哪些…

Vue--BM记事本

效果如下&#xff1a; 用到了如下的技术&#xff1a; 1.列表渲染&#xff1a;v-for key的设置 2.删除功能&#xff1a;v-on调用参数 fliter过滤 覆盖修改原数组 3.添加功能&#xff1a;v-model绑定&#xff0c;unshift修改原数组添加 html文件如下&#xff1a; <!DOCTYPE …

1.进程控制

1.进程概念 进程是管理事务的基本单元 2.并发并行 并行(parallel)&#xff1a;指在同一时刻&#xff0c;有多条指令在多个处理器上同时执行。并发(concurrency)&#xff1a;指在同一时刻只能有一条指令执行&#xff0c;但多个进程指令被快速的轮换执行&#xff0c;使得在宏观上…

7-5 特殊a串数列求和

分数 20 全屏浏览题目 切换布局 作者 颜晖 单位 浙大城市学院 给定两个均不超过9的正整数a和n&#xff0c;要求编写程序求aaaaaa⋯aa⋯a&#xff08;n个a&#xff09;之和。 输入格式&#xff1a; 输入在一行中给出不超过9的正整数a和n。 输出格式&#xff1a; 在一行中…

回归预测 | MATLAB实现NGO-SVM北方苍鹰算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现NGO-SVM北方苍鹰算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现NGO-SVM北方苍鹰算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基…

华为网络篇 多区域OSPF-32

难度2复杂度2 目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 OSPF是一种具有区域概念的路由协议&#xff0c;为什么需要分区域&#xff1f;像RIP那样都在一个区域配置也不多这样简单点不是更好吗&#xff1f;OSPF它是一种功能十分强大的IG…

基于Java+SpringBoot+Vue的学校田径运动会管理系统【源码+论文+演示视频+包运行成功】

博主介绍&#xff1a;✌擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案…

本地事务和分布式事务

参考连接分布式事务有这一篇就够了&#xff01; - 知乎 (zhihu.com) 本地事务 使用服务自己的数据库来控制事务&#xff0c;我们常使用的transaction注解。transaction注解是基于spring基于aop思想利用数据库的事务来进行事务控制。 begin transaction&#xff1b;//1.本地数…

go语言中channel类型

目录 什么是channel 为什么要有channel channel操作使用 初始化&#xff1a; 操作&#xff1a; 单向channel 双向channel&#xff0c;可读可写&#xff1a; close下什么场景会出现panic 总结 什么是channel Channels are a typed conduit through which you can send …

RabbitMQ介绍及常见消息队列

1. RabbitMQ 1.1. 搜索与商品服务的问题 假设我们已经完成了商品详情和搜索系统的开发。我们思考一下&#xff0c;是否存在问题&#xff1f; o 商品的原始数据保存在数据库中&#xff0c;增删改查都在数据库中完成。 o 搜索服务数据来源是索引库&#xff0c;如果数据库商品发…

QT C++实现简易便签

总想着下载一个便签出来自己用&#xff0c;但网上下载的不是功能太多&#xff0c;好多功能都用不到&#xff0c;就是功能太少了&#xff0c;或是界面不太符合自己审美。所以干脆想着自己做一个算了&#xff0c;反正也不是很麻烦。 需求功能&#xff1a; 开机自启动&#xff0c…

无涯教程-PHP - 循环语句

PHP中的循环用于执行相同的代码块指定的次数。 PHP支持以下四种循环类型。 for - 在代码块中循环指定的次数。 while - 如果且只要指定条件为真&#xff0c;就会循环遍历代码块。 do ... while - 循环执行一次代码块&#xf…

Over Permision

文章目录 水平越权垂直越权 如果使用A用户的权限去操作B用户的数据&#xff0c;A的权限小于B的权限&#xff0c;如果能够成功操作&#xff0c;则称之为越权操作。 越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的。 一般越权漏洞容易出现在权限页面&#xff08;需…

什么是cURL?

cURL无处不在。它几乎隐藏在所有设备中&#xff0c;例如汽车&#xff0c;蓝光播放器等。它通过互联网协议传输任意类型数据。 在本文中&#xff0c;我们将揭开cURL神秘命令行工具的面纱&#xff0c;解释它是如何成为一种通用代码的&#xff0c;并举例说明其用法。 cURL是什么意…

[MAUI]模仿网易云音乐黑胶唱片的交互实现

用过网易云音乐App的同学应该都比较熟悉它播放界面。 这是一个良好的交互设计&#xff0c;留声机的界面隐喻准确地向人们传达产品概念和使用方法&#xff1a;当手指左右滑动时&#xff0c;便模拟了更换唱盘从而导向切换歌曲的交互功能。 今天在 .NET MAUI 中我们来实现这个交互…

地球IT

地球是我们生活的家园&#xff0c;也是人类发展的基地。地球不仅仅是一个行星&#xff0c;更是一个复杂而有机的生态系统。 地球直径约为12,742公里&#xff0c;被称为“蓝色星球”&#xff0c;因为它的表面约70%被水覆盖。海洋是地球上最大的生态系统之一&#xff0c;它们扮演…

商城-学习整理-高级-商城业务-异步线程池(十三)

目录 一、线程1、初始化线程的 4 种方式2、线程池的七大参数3、线程池的运行流程&#xff1a;4、例子5、常见的 4 种线程池6、开发中为什么使用线程池 二、CompletableFuture 异步编排0、业务场景&#xff1a;1、创建异步对象2、计算完成时回调方法3、handle 方法4、线程串行化…

springboot 项目日志配置文件详解

spring boot 项目指定 日志配置文件 在Spring Boot项目中&#xff0c;可以通过在application.properties或application.yml文件中指定日志配置文件来配置日志。 1. 使用application.properties文件&#xff1a; 在application.properties中&#xff0c;您可以使用以下属性来…

系统卡死问题分析

CPU模式 CPU Frequency Scaling (CPUFREQ) Introduction CPU频率调节设备驱动程序的功能。该驱动程序允许在运行过程中更改CPU的时钟频率。一旦CPU频率被更改,必要的电源供应电压也会根据设备树脚本(DTS)中定义的电压值进行变化。通过降低时钟速度,这种方法可以减少功耗…