Java面试题 -- 为什么重写equals就一定要重写hashcode方法
在回答这个问题之前我们先要了解equals与hascode方法的本质是做什么的
1. equals方法
public boolean equals(Object obj) {return (this == obj);}
我们可以看到equals在不重写的情况下是使用==判断地址值是否相同
所以默认的 equals 的逻辑就是判断的双方是否引用了一个对象,如果是那就是相等的,如果不是那就不相等。
默认的 equals 看似能满足我们的要求,但有些情况下却不能。在开发过程中,我们更希望比较的是两个对象的内容是否相等
package com.Month08.Day_02;import java.util.Objects;public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public Person() {}
}
package com.Month08.Day_02;import java.util.stream.Stream;public class Test {public static void main(String[] args) {Person a = new Person("a",4);Person b = new Person("a", 4);System.out.println(a.equals(b));}
}
可以看到在这里我们传入相同的值的情况下得到的结果却是false
2. HashCode
简而言之hashcode是通过将内部存储地址映射成一个整型值,这个整型值就是hashcode
默认情况下,hashCode()方法返回的是对象的内存地址的哈希码表示。
public int hashCode() {int h = hash;if (h == 0 && !hashIsZero) {h = isLatin1() ? StringLatin1.hashCode(value): StringUTF16.hashCode(value);if (h == 0) {hashIsZero = true;} else {hash = h;}}return h;}
3. 什么是散列表
在Java中,散列表(Hash Table)是一种非常重要的数据结构,它通过哈希函数(Hash Function)将输入(通常是键Key)映射到表中一个位置来访问记录,以加快查找的速度。散列表通常是以数组的形式实现的,但不同于普通的数组,散列表中的每个槽位(slot)并不直接存储数据,而是存储数据的索引(或称为指针),这个索引指向实际存储数据的位置。这种设计使得数据的查找、插入和删除操作都非常快
- HashMap:这是Java中最常用的类之一,它实现了Map接口,是一个基于哈希表的Map接口的非同步实现。HashMap允许使用null值和null键,不保证映射的顺序;特别是它不保证该顺序随时间的推移保持不变。
- Hashtable:虽然名为Hashtable,但它实际上也是一个散列表的实现。不过,与HashMap相比,Hashtable是同步的,这意味着它在多线程环境下是安全的。但是,由于同步操作带来的开销,Hashtable在单线程环境下的性能通常低于HashMap。另外,Hashtable不允许键或值为null。
- LinkedHashMap:这个类扩展了HashMap,并维护了一个运行于所有条目的双重链接列表。这个链表定义了迭代器遍历条目的顺序,该顺序可以是插入顺序或者是访问顺序(取决于构造器中的accessOrder参数)。
- TreeMap:虽然TreeMap不是基于哈希表的,但它实现了Map接口,并且可以看作是一种有序的映射(基于红黑树实现)。这里提到它是因为它在某些方面与HashMap等散列表实现有对比意义。
3. 只重写equals会导致什么问题?
在这个Person类中我们只重写了equals方法
package com.Month08.Day_02;import java.util.Objects;public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public Person() {}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && Objects.equals(name, person.name);}}
如何我们在测试类中new两个对象 , 因为此时的euqals方法已经被重写 , 尽管对象a , b的地址值不同但是因为都是空参 , 也就是传入的值相同会使得a.equals(b)为true , 但是优惠遇到一个问题也就是HashCode值不相同
package com.Month08.Day_02;import java.util.stream.Stream;public class Test {public static void main(String[] args) {Person a = new Person();Person b = new Person();System.out.println(a); // com.Month08.Day_02.Person@214c265eSystem.out.println(b); // com.Month08.Day_02.Person@448139f0System.out.println(a.hashCode()); // 558638686System.out.println(b.hashCode()); // 1149319664System.out.println(a.equals(b)); // true}
}
我们知道在散列表中如hashmap中 , 在储存元素之前会通过计算key的值来确定key是否重复 , 那么回到上面的问题 , 如果 我们将a , b这两个对象作为key进行储存 , 通过HashCode计算发现他们HashCode不相同 , 那么这两个对象到底是相同的还是不同的呢?
HashMap<Person, String> map = new HashMap<>();map.put(a , "123");map.put(b , "456");System.out.println(map.get(a)); //123System.out.println(map.get(b)); // 456
所以为了避免这样的问题 , 我们在重写equals的时候同时需要重新hashcode
相关文章:

Java面试题 -- 为什么重写equals就一定要重写hashcode方法
在回答这个问题之前我们先要了解equals与hascode方法的本质是做什么的 1. equals方法 public boolean equals(Object obj) {return (this obj);}我们可以看到equals在不重写的情况下是使用判断地址值是否相同 所以默认的 equals 的逻辑就是判断的双方是否引用了一个对象&am…...

J031_使用TCP协议支持与多个客户端同时通信
一、需求文档 使用TCP协议支持与多个客户端同时通信。 1.1 Client package com.itheima.tcp2;import java.io.DataOutputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner;public class Client {public static void main(String[] a…...
二分查找(精确查找、范围搜索)
目录 1. 二分查找概述2. 精确查找2.1 【left,right】2. 2 【left,right) 3. 范围查找总结 1. 二分查找概述 二分查找法,也称为二分搜索法或折半查找法,是一种在有序数组中查找特定元素的搜索算法。其基本思想是&#x…...
软件工程简记
文章目录 一、软件工程要点之软件设计二、UML(Unified Modeling Language,统一建模语言)(一)UML 的整体分类与部分功能(二)UML 各类图的具体内容三、开发模型(一)多种开发模型的特点与问题四、设计模式(一)设计模式的总体概念与原则(二)软件结构设计原则(三)常见…...

【深度学习】【语音TTS】OpenVoice v2,测评,中英文语料,Docker镜像,对比GPT-SoVITS、FishAudio、BertVITS2
https://github.com/myshell-ai/OpenVoice/blob/main/docs/USAGE.md 实际体验OpenVoice v2的TTS效果。 文章目录 环境启动 jupyter代码代码分析主要模块和功能测试一些别的中文和中英文混合总结优点缺点对比GPT-SoVITS、FishAudio、BertVITS2使用我的Docker镜像快速体验OpenVo…...

Kotlin OpenCV 图像图像50 Haar 级联分类器模型
Kotlin OpenCV 图像图像50 Haar 级联分类器模型 1 OpenCV Haar 级联分类器模型2 Kotlin OpenCV Haar 测试代码 1 OpenCV Haar 级联分类器模型 Haar级联分类器是一种用于对象检测(如人脸检测)的机器学习算法。它由Paul Viola和Michael Jones在2001年提出…...

嗖嗖移动业务大厅(Java版)
首先对此项目说明一下,我只完成了项目的基本需求,另外增加了一个用户反馈的功能,但是可能项目中间使用嗖嗖这个功能还有一些需要完善的地方,或者还有一些小bug,就当给大家参考一下了,希望谅解。代码我也上传…...
hcia复习笔记
一、OSI 七层模型 应用层:为应用程序提供服务,如文件传输、电子邮件等。 表示层:数据格式转换、加密解密、压缩解压缩。 会话层:建立、维护和管理会话。 传输层:提供端到端的可靠或不可靠的数据传输服务࿰…...

pycharm中安装、使用扩展工具,以QT Designer为例
pycharm中安装、使用扩展工具,以QT Designer为例 第一步,下载QT Designer安装包。找到QT Designer.exe所在位置,复制路径 第二步,打开Pycharm,选择Setting,找到扩展工具(External Tools…...
【Rust光年纪】Rust语言实用库汇总:从机器翻译到全文搜索引擎
优秀的Rust语言库探索:机器翻译、音频编解码和全文搜索引擎 前言 Rust语言在近年来迅速崛起,成为了一种备受欢迎的系统级编程语言。随着其生态系统的不断丰富,涌现出了许多优秀的库和工具。本文将重点介绍几个用于Rust语言的重要库…...

学习笔记 - 二极管的参数与选型
二极管 普通二极管: 1N4148(高频开关二极管) 整流二极管: 1N4007 1A 1000V1N5408 3A 1000V 肖特基二极管 (白线边为阴极) SS14 SS34 SS54 常见肖特基二极管参数 快恢复二极管 FR107 FR207 FR307 UF4007 可以用快恢复二…...

PMP--冲刺--易混概念
文章目录 十大知识领域一、整合管理项目管理计划与项目文件的区分: 二、范围管理三、进度管理赶工与快速跟进的区分:赶工增加资源,以最小的成本代价来压缩进度工期;快速跟进,将正常情况下按顺序进行的活动或阶段改为至…...

Resolving Maven dependencies
Maven是一种项目管理和构建工具,通常用于Java项目。这个过程包括下载项目所需的所有外部库和插件,并将它们添加到项目的构建路径中。具体来说,它正在处理名为“AAS_byBasyx”的项目或模块的依赖项。这种任务通常在你打开一个新的Maven项目或更…...

【Spring】SSM框架整合Spring和SpringMVC
目录 1.项目结构 2.项目的pom.xml文件 3.spring.xml和springMVC配置文件 4.database.properties和mybatis.xml配置文件 5. 代码编写 6.测试整合结果 1.项目结构 首先创建一个名为ssm_pro的Mavew项目,然后再在主目录和资源目录下,创建如下所示的结…...

优维2024年中思考:大模型赋予新一代运维的“非产品性”启示
近年来,人工智能在各个行业的应用大幅增加,人工智能技术取得重大进步的领域之一是IT运维。 去年四季度,优维科技敏锐地提出“新一代运维核心系统提供商”的战略新定位,决定将“DevOps及运维”回归到“运维”本身,但我…...
【中药网络药理学】筛选细胞衰老和预后相关基因(附分类代码和画图代码)
1、衰老相关基因 从HAGR和msigdb数据获取细胞衰老相关基因,将两者取交集后构建基因蛋白互作网络 HAGR数据库 该库本身提供了下载链接,我在下载后对其进行了清洗 msigdb数据库 以"aging"作为关键词,Search Filters中collection…...

华为的流程体系
缘由 2010年,华为销售额为1850亿元,其中国际市场占65%,净利润238亿元。当时,公司员工达11万人,公司处理合同达5万多个,290万个订单,大量的工作是手工处理,没有统一的流程支持&#…...
算法——长度最小的子数组209 对比代码随想录题解中对于result取值为Integer.MAX_VALUE的思考
具体解题过程可看代码随想录,我主要是对于为什么result也就是子数组和初始化要为Integer.MAX_VALUE有一个疑惑,为什么不是其他值,经过思考后我发现: 情况一:如果result为负数的话是不符合数组长度取值的一个规范的。 情况二&…...
图像处理案例03
HOGSVM数字识别 1 . 步骤2 . 代码 1 . 步骤 读入数据,把数据划分为训练集和测试集用hog提取特征用SVM训练数据测试、评价模型保存模型加载模型,应用模型 2 . 代码 import os import cv2 import sklearn import numpy as np from skimage.feature impo…...

【Kubernetes】k8s集群中kubectl的陈述式资源管理
目录 一.k8s集群资源管理方式分类 1.陈述式资源管理方式 2.声明式资源管理方式 二.陈述式资源管理方法 三.kubectl命令 四.项目生命周期 1.创建 kubectl create命令 2.发布 kubectl expose命令 3.更新 kubectl set 4.回滚 kubectl rollout 5.删除 k…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...

《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...