为什么重写equals方法也要重写hashcode方法

equals和hashcode方法重写 在 Java 中,当你需要来判断两个对象是否相等时,就需要重写equals和hashCode方法。 阅读详情

转https://blog.youkuaiyun.com/wusuopubupt/article/details/77162126

为什么在覆盖equals时一定也要覆盖hashCode?

因为先hashmap, 后equals !

下面用HashMap来阐述原因,首先假设key1和key2的值在业务逻辑领域是相等的,即它们应该是同一个对象,HashMap已经存储了key1,现在要查找key2是否存在,正确的结果应该是存在。

Java中的HashMap实际上是一个链表数组,即首先HashMap是一个数组,然后数组中的每一个元素是一个链表(更通用的概念可以称为桶bucket,Java中的HashMap用Entry类描述链表的结点结构),HashMap在执行Put,Contains之类的操作时,会首先根据你提供的Key计算hashCode值,然后根据这个hashCode值在数组中找到某一个链表或桶(通常是找到链表的起始结点),这一步操作利用了hashCode()方法,如果你覆盖了就会用你提供的方法,在找到某一个链表的起始结点后,就会遍历链表,然后通过equals方法来寻找是否存在与Key的值相等的结点,如果执行equals方法后的结果相等,HashMap就认为已经存在这个元素,这一步如果你覆盖了equals方法就会用到你提供的equals方法。

通过上面的描述,我们发现equals方法和hashCode方法如果不同时按你自己逻辑覆盖的话,HashMap就会出问题。比如你只覆盖了equals方法而没有覆盖hashCode方法,那么HashMap在第一步寻找链表的时候会出错,有同样值的两个对象Key1和Key2并不会指向同一个链表或桶,因为你没有提供自己的hashCode方法,那么就会使用Object的hashCode方法,该方法是根据内存地址来比较两个对象是否一致,由于Key1和Key2有不桶的内存地址,所以会指向不同的链表,这样HashMap会认为key2不存在,虽然我们期望Key1和Key2是同一个对象;反之如果只覆盖了hashCode方法而没有覆盖equals方法,那么虽然第一步操作会使Key1和Key2找到同一个链表,但是由于equals没有覆盖,那么在遍历链表的元素时,key1.equals(key2)也会失败(事实上Object的equals方法也是比较内存地址),从而HashMap认为不存在Key2对象,这同样也是不正确的。

以下内容摘自Effective Java:

覆盖equals时总要覆盖hashCode,一个很常见的错误根源在没有覆盖hashCode方法。在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,这样的集合包括HashMap、HashSet和Hashtable。

下面是约定的内容,摘自Object规范[JavaSE6]:

  • 在应用程序的执行期间,只要对象的equals方法所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。

  • 如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。

  • 如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中的任意一个对象的hashCode方法,则不一定要产生不同的整数结果。但是程序员应该知道,给不相同的对象产生截然不同的整数结果,有可能提高散列表(hash table)的性能。

为什么在重写 equals方法的同时必须重写 hashcode方法 Object 类是所有类的父类,其 equals 方法比较的是两个对象的引用指向的地址,hashcode 是一个本地方法,返回的是对象地址值。他们都是通过比较地址来比较对象是否相等的 立即下载

相关推荐

java中重写equals()方法的同时要重写hashcode()方法(详解)

下面小编就为大家带来一篇java中重写equals()方法的同时要重写hashcode()方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

为什么重写equals方法时一定要重写hashCode方法

在每个类中,在重写 equals 方法的时侯,一定要重写 hashcode 方法。如果不这样做,你的类违反了 hashCode的通用约定, 这会阻止它在 HashMap 和 HashSet 这样的集合中正常工作。 根据 Object 规范,以下时具体约定。 当在一个应用程序执行过程中, 如果在 equals 方法比较中没有修改任何信息, 在一个对象上重复调用 hashCode 方法时,它必须始终返回相同的值。从一个应用程序到另一个应用程序的每一次执行返回的值 可以是不一致的。 如果两个对象根据 equal

骑个小蜗牛的博客 3万+

稀疏阵列选型指南:互质阵、嵌套阵、MRA,谁才是你项目里的‘性价比之王’?

本文深入探讨了稀疏阵列技术中的互质阵、嵌套阵和MRA三大架构的工程化选型策略,重点分析了它们在DOA估计、自由度、旁瓣抑制和计算复杂度等核心指标上的表现。通过实际案例和配置示例,为智能天线、声学定位和毫米波雷达等应用场景提供技术选型指南,帮助研发团队在硬件成本与性能之间找到最佳平衡点。

weixin_42525005的博客 489

重写equals为什么还要重写hashcode

2、在散列集合中,是使用hashcode来计算key应存储在hash表的索引,如果重写了equals而没有重写hashcode,会出现两个完全相同的两个对象,hashcode不同,计算出的索引不同,那么这些集合就乱套了。3、提高效率,当我们比较两个对象是否相同的时候,先比较hashcode是否相同,如果hashcode不相同肯定不是一个对象,如果hashcode不同再调用equals来进行比较,减少比价次数提高效率。1、为了保证一个原则,equals相同的两个对象hashcode必须相同。

weixin_53425597的博客 4026

Unity雷达图效果实现

unity雷达图源码

a604263644的博客 1026

将Matlab程序打包成.exe独立可执行程序

将Matlab程序打包成.exe独立可执行程序,在未安装Matlab的电脑上也能运行Matlab程序。

简简单单的学习笔记,致力于帮助更多前进路上的朋友~ 5万+

为什么覆盖equals时总要覆盖hashCode

为什么覆盖equals时总要覆盖hashCode 一个很常见的错误根源在于没有覆盖hashCode方法。 在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。 如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMap、HashSet和Hashtable。 1.在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一

weixin_43273005的博客 764

为什么重写 equals 时必须重写 hashcode 方法

我们常常说,重写Equals时必须要重写HashCode,那么是为什么呢? 原因见下: 每个覆盖了equals方法的类中,必须覆盖hashCode。如果不这么做,就违背了hashCode的通用约定,也就是上面注释中所说的。进而导致该类无法结合所以与散列的集合一起正常运作,这里指的是HashMap、HashSet、HashTable、ConcurrentHashMap。 现在我们来做一个实验证明重写Equals时一定要重写HashCode public class EqualAndHashCodeTest {

想好名字再改 217

实战对比:Lmcache+vllm将KVcache卸载到CPU和SSD的性能差异(附完整配置)

本文通过实战对比Lmcache与vLLM在KV Cache卸载到CPU和SSD的性能差异,详细解析了配置优化、基准测试及高级调优策略。实验显示,CPU卸载在低并发下表现优异,而SSD方案在高并发场景中更具性价比优势,为LLM推理任务提供了高效的存储解决方案。

weixin_30664051的博客 701

从模型车到真实路口:基于YOLOv5-Lite与SORT的轻量化车流量检测系统实战

本文详细阐述了如何将基于YOLOv5-Lite与SORT的轻量化车流量检测系统从毕业设计原型部署到真实路口。文章聚焦于解决在嵌入式平台(如树莓派)上实现实时、稳定检测的工程挑战,涵盖数据采集、模型微调、系统集成及动态信号灯策略,为智能交通灯系统提供了实用的轻量化解决方案。

weixin_29179311的博客 128

【Java面试】为什么重写equals方法必须同时重写HashCode方法?

对于散列集合,他们使用的是hashcode来判断是否是相同的,如果存储两个相同的对象,但是他们的hashcode值不同,那么就会导致这两个对象存储在hash表的两个不同的位置,然后当我们想要获取数据的时候,就会出现一个完全相同的对象,会存储在hash表的两个位置,就会破坏程序开发过程中我们约定俗成的规则,就会出现一些不可预料的错误。而如果重写了equals方法,但是没有重写hashCode方法,那么就会导致hashcode值可能不一样,而如果出现这种情况,就会导致这个类无法和所有的集合类一起工作。

Zhangsama1的博客 1040

《QGIS快速入门与应用基础》009:国内镜像源(清华大学/阿里云)下载技巧

针对国内用户下载QGIS速度慢、易中断的问题,推荐使用清华大学和阿里云两大国内镜像源,提供3-10MB/s的极速下载方案。详细解析镜像源核心优势、分步骤下载指南及校验方法,对比清华(同步快、北方优选)与阿里云(南方节点多)的特点。针对常见问题如版本延迟、404错误等提供解决方案,并介绍搭配IDM等工具实现多线程加速的进阶技巧。通过镜像源+下载工具组合,用户可高效获取QGIS安装包,为后续系统安装奠定基础。

LuckyHanMo的博客 1751

重写hashcode和equals方法

一。前言 我们都知道,要比较两个对象是否相等时需要调用对象的equals()方法,即判断对象引用所指向的对象地址是否相等,对象地址相等时,那么与对象相关的对象句柄、对象头、对象实例数据、对象类型数据等也是完全一致的,所以我们可以通过比较对象的地址来判断是否相等。 二。Object源码理解 对象在不重写的情况下使用的是Object的equals方法和hashcode方法,从Object...

简乐君 7万+

2026.2.23:AgentScope框架实战<一>:安装并使用agentscope

本文介绍了AgentScope框架的安装与使用实践。通过PyPI安装agentscope[full]后,演示了如何创建ReActAgent代理:1)配置DashScope聊天模型;2)注册自定义工具函数(查询位置和天气);3)初始化代理并处理用户请求。示例展示了代理如何响应复合查询(如同时获取北京位置和天气信息),输出结果显示代理成功执行了工具调用并返回结构化响应。该框架支持Python 3.13环境,提供内存管理、工具集成等功能,适用于构建智能代理系统。

拥抱具身智能,昇腾Ascend C 512

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

为什么重写equals方法,还必须要重写hashcode方法

为什么? 是为了提高效率,采取重写hashcode方法,先进行hashcode比较,如果不同,那么就没必要在进行equals的比较了,这样就大大减少了equals比较的次数,这对比需要比较的数量很大的效率提高是很明显的,一个很好的例子就是在集合中的使用; 我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元...

代码君的博客 4万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java中重写equals()方法的时候为什么要重写hashCode()方法?

有时候,或许会听到被人说,在重写equals方法的时候,记得重写hashcode方法。那么自然有这样的疑问,那么为什么这样?equals方法和hashCode方法是什么关系?不重写的时候会有什么危害?文章将从一下几个方面进行叙述。 一:什么是hashCode(),equals()方法? 二:hashCode(),equal()s两种方法是什么关系? 三:为什么在重写equals方法的

南瓜灯cc 3万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

为什么重写equals方法时必须重写hashcode方法

文章目录1. == 与 equals的区别2. 重写equals()3. hashCode与equals的区别和联系3.1 Hash3.2 HashCode 1. == 与 equals的区别 如果两个引用类型变量使用==运算符,那么比较的是地址,它们分别指向的是否是同一地址的对象,结果一定是false,因为两个对象地址必然不同。 ==不能实现比较对象的值是否相同。 所有对象都有equals方法,默认是Object类的equals,其结果与==一样。 如果希望比较对象的值相同,必须重写equ

m0_45406092的博客 6275

equals方法与hashcode方法的重写

很显然,输出的结果无论是用的==比较还是用的equals比较都是false;散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的。经过哈希表达式计算后的hashcode相等的实在不好找,就不敲代码测试了,欸嘿~当发生冲突时,对应的存储单元以链表的形式保存冲突的数据(链地址法)。常见的散列表实现方式:用数组作为哈希函数的输出域,引用类型的变量所指向的对象的地址。

SuYuewu的博客 1915

为什么重写equals方法时必须重写hashCode方法

为什么重写equals时必须重写hashCode方法 Java中的hash值主要是用来在散列存储结构中确定对象的存储地址的,提高对象的查询效率。 Java设计的顶级父类Object类中,有两个方法很特殊,它们分别是equals方法与hashCode方法。——一旦重写了equals方法,就一定要重写hashCode方法。以下是Object的源码: public class Object { /* * Note that it is generally necessary to override th

xingyu19911016的博客 7114

为什么重写Equals方法要重写HashCode方法

重写

WinnerBear的博客 3767

为什么重写equals还要重写hashcode方法

为什么重写equals还要重写hashcode方法

Knight 1976

为什么重写equals()方法的同时要重写hashCode()方法

原文地址:https://www.jianshu.com/p/3819388ff2f4 equals方法和hashCode方法都是Object类中的方法,我们来看看他们的源码: public boolean equals(Object obj) { return (this == obj); } public native int hashCode(); 可知,...

小名同学 21万+

怎么重写equals()方法和hashCode()方法

equals()

qq_63882368的博客 1697

为什么重写equals方法之后必须要重写hashCode

默认的equals看似能满足我们的要求,实则不然,多数情况下,我们更希望比较的是两个对象的内容是否想,比如两个字符串,String a = "12345",String b = "12345",内容完全一样,在我们看来这两个字符串就是相等的,但在equals方法看来,两个字符串的内存地址不相等,所以仍然会判定为不相等,这就与我们的判断结果发生了矛盾,所以我们需要去重写equals方法,只有重写了equals方法之后,我们再去判断a和b,这是判断结果才会相等。为什么遇到散列表,上面的代码就会出错呢?

m0_70325779的博客 1778
上一篇: 基于java api的spark常用算子
下一篇: kafka常用命令
Java_Soldier
博客等级 码龄10年 27粉丝 82原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值