Java重写equals方法时为什么要重写hashCode方法

在我们平时编写Java代码时,重写equals方法时一定要重写hashCode方法,这是为什么呢?

在讨论这个问题前,我们先看下Object类中hashCode方法和equals方法。

hashCode方法:

img

翻译如下:

img

equals方法:

img

翻译如下:

img

1、hashCode方法的作用

在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。

为什么这么说呢?考虑一种情况,当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?

也许大多数人都会想到调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。

此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。

java.util.HashMap的中put方法的具体实现,先计算key的hash值,从table数组中取出对应节点,如果节点不存在则添加一个节点;如果存在则更新value,返回旧value。

img

hash方法会调用对象的hashCode()方法:

img

addEntry方法添加新节点:

img

new一个Entry实例,next指向原有的Entry实例。也就是新new的Entry实例是该链表的头。

img

Entry是一个静态内部类,有一个属性next,指向下一个Entry,形成一个链表结构。

img

2、equals方法和hashCode方法

看下面代码:

img

输出结果:

img

我们Student类重写了equals方法,hashCode方法没有重写,s1和s2的姓名和年龄相同,equals方法为true,认为是同一个人。但是s1和s2的hashCode返回不同。

我们看下hashMap的get方法,先获取key的hashCode,由于s1和s2的hashCode不同,所以hashMap.get(s2)得到的是null。

img

img

接下来我们重写下Student类的hashCode方法,让equals方法和hashCode方法始终在逻辑上保持一致性。

img

重新运行,输出结果如下,s1和s2的hashCode相同了,hashMap.get(s2)得到了1。

img

① 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。

② 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。

③ 如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

如果hashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化时,hashCode()方法就会生成一个不同的hash值。看下面例子:

img

修改了age属性的值,导致hashCode变化,所以输出为“null”。

因此,在设计hashCode方法和equals方法的时候,如果对象中的数据易变,则最好在equals方法和hashCode方法中不要依赖于该字段。

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

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

相关文章

iot nb 曹淑敏 鹰潭_移动物联时代来啦 鹰潭一项成就为全球首个 江西力争在全国“四个领先”...

移动物联网是基于移动通信网络的物联网技术体系,主要由NB-IoT(窄带物联网技术)、eMTC(增强机器类通信技术)、蜂窝网的未来演进技术5G(第五代移动通信技术)三种技术共同构成。江西网络广播电视台9月1日讯(记者 李希文)9月1日下午,江西省工信委、中国信息通…

RPC(一)[概述]

文章目录RPC-概述简介1.服务的调用过程2.RPC框架1.Dubbo–电商2.Motan–互联网3.Thrift4.gRPC5.RPCX3.RPC 和 RESTful1.RPC over HTTP 和 RESTful2.RPC over TCP 和 RESTfulRPC-概述 简介 远程过程调用(Remote Procedure Call,缩写为 RPC)是…

epic登陆按钮一直在转_双剑合璧!GOG GALAXY 2.0官方支持Epic商店集成

2020年7月21日晚,GOG官方宣布提供与Epic商城的集成服务,这也是GOG GALAXY 2.0推出以来又一次与超大型游戏平台达成的合作。现在玩家可以通过GOG GALAXY 2.0管理、安装和启动来自Epic商城的游戏。需要注意的是,因为这次行为是完全官方的&#…

用 Java 实现人脸识别功能

引言 人脸识别SDK 人脸识别技术是很复杂的,自己用Java手撕一个识别算法有点不切实际,毕竟实力不允许我这么嚣张,还是借助三方的SDK吧! 找了一圈发现一个免费的人脸识别SDK: ArcSoft:,地址:ht…

有没有词匹配算法_Google Ads 再次扩展了关键字变量匹配

在过去的几年里,Google Ads已经扩大了使用相近的关键字变量。Google改变的匹配类型不仅包括拼写错误和复数,还包括功能词、修改和重新排序。日前,谷歌再次扩展了相近变量的使用。短语匹配和广泛匹配修饰语以下是2019年7月31日谷歌官方广告公告…

mysql 组合查询_MySQL组合查询教程

#MYSQL#这是我MySQL的第八篇教程。本篇主要介绍的是MySQL的组合查询的用法。在大多数的SQL查询中都只包含从一个或者多个表中返回数据的单条SELECT语句,MySQL其实也支持允许执行多条SELECT语句,并将结果作为单个结果集返回,这些组合查询通常称…

Java后端 + 百度SDK实现人脸识别

Java后端 百度SDK实现人脸识别 人工智能越来越贴近我们的生活,相信大家也经常接触到人脸识别,手机付款、app注册验证、门禁等等。 如果要用Java后台使用这些功能,那么需要怎么做呢?请看完下面这篇文章,就能轻松、简单…

路由器局域网设置_路由器基础介绍

路由器已经商用很多年了,但是一些SSID, DHCP, 这些名词都还没有搞懂,遇到路由器问题,不知所措,只能求助于网管。但是有些问题是很简单的,只要稍微去学习就可以解决问题。下面介绍路由器的一些简单问题。路由…

mysql主键设置after_mysql如何改变主键属性

mysql改变主键属性的方法:1、使用关键字modify,代码为【alter table tbl_name modify.....】;2、使用关键字change,代码为【alter table tbl_name change..】。本教程操作环境:windows7系统、mysql8.0.22版&#xff0c…

python打包成exe_Python打包成exe时,再犯这几个错误就说不过去了

大家好,我是今天的值班小编,不知道朋友们开工了没有,小编的公司已经远程办公好几天了。今天由于写游戏教程的那位小编弃坑不更新文章了,只好由本小编继续来解决粉丝朋友们的问题。 如果朋友们在使用python的过程中遇到了任何问题&…

机器视觉 光学工程专业_瑞士Idonus MEMS制造设备 创新技术 机器视觉测量(远心光学)...

机器视觉从图像处理算法到光学安装,idonus 提供部分或全部机器视觉解决方案。典型应用包括机械零件的高通量自动测量、表面质量检测、定位、质量控制或识别。我们定制开发的解决方案可与机器人化或手动设备相结合。我们的报价:定制硬件和软件&#xff0c…

vs 中使用32 位mysql_vs2010连接mysql数据库(含win32和x64两种平台)

数据库安装: 此处有两种安装方式,第一种使用xxx.msi图形化安装方式,和普通的exe软件安装方式一样,按照默认选项一直下一步就可以。mysql下载地址为http://dev.mysql.com/downloads/windows/installer/ 第二种是在mysql官网下载zip…

电脑时间校对器_笔记本电脑如何保养?华为教你五招轻松延长使用时间

集微网7月11日消息(文/数码控),近日华为花粉俱乐部官方微信公众号发表长文教用户如何保养笔记本电脑,具体有以下五招:

uvc能支持多大分辨率_华为手环B5测评:该有的功能一个不缺,甚至还能变身蓝牙耳机...

前阵子,华为召开nova5系列新品发布会的同时,也给用户们带来了华为手环B5的新配色--铅石青。华为手环B5在去年7月发布,分为三个版本:运动版999元、商务版1199元、时尚版1499元。​此次更新的是运动版,售价仍为999元&…

cf不能全屏win7的解决方法_win7系统局域网不能访问怎么办 win7局域网不能访问解决方法...

在局域网当中比较实用的功能要数共享文件了,局域网共享可以让用户们共享和管理资源更加便捷,可以大大提高工作效率,不过最近有位win7系统用户使用电脑的时候,发现电脑无法访问局域网中的其他任何一台电脑,这让用户不知…

CGLib动态代理原理

CGLib动态代理原理 CGLib动态代理是代理类去继承目标类,然后重写其中目标类的方法啊,这样也可以保证代理类拥有目标类的同名方法; 看一下CGLib的基本结构,下图所示,代理类去继承目标类,每次调用代理类的方…

sql读取excel数据_Python 读取 Excel 数据,并插入到MySQL

说实话,个人不建议用Python来读取Excel进行入库操作,有条件的话,可以尝试用 ETL 工具,快速导入到MySQL中,或者也可使用 SQL 的导入工具进行。写本文的目的在于:记录一下之前做过一次这个同类型的东西。也为…

无向图的深度优先遍历非递归_图算法总结

[TOC]图算法1、图的表示1.1、邻接矩阵(有向图、无向图、带权图、代码实现)1、无向图的邻接矩阵 2、有向图的邻接矩阵 3、带权值的图 有了上述的理解,我们可以设计数据结构,并实现了。C实现如下:#include1.…

华为ipd项目管理流程_IPD:一套卓越的产品开发经营体系

IPD全流程指的不仅仅是“产品开发流程”,而是如何实现产品“从机会到商业变现”的全流程。华为通过20年的全流程实践,才做到持续性推出高质量产品和解决方案。本期IPD全流程班,帮助企业研发管理者学习这套结构化流程,其中划下重点…

Springboot中@ComponentScan 注解

三个点: 1、工程中Application类的位置。默认情况下就不需要配置ComponentScan这个注解了。 因为Application类,在启动的时候,默认是加载和Application类所在同一个目录下的所有类,包括所有子目录下的类。所以一般情况下&#xff…