深入理解equals和hashCode关系和区别

深入理解equals和hashCode关系和区别

  • 直入主题:
    • 区别:
      • 1.他们判断对象相同的方式不一样:
      • 2.他们判断对象是否相等的准确率不一样:
    • 改写equals时总是要改写hashcode
    • 分享一波:程序员赚外快-必看的巅峰干货

为什么要说equals和hashCode这两个东西,一来是因为有不少小伙伴面试时被问过这个东西,二来则是因为如果了解了这两个东西的原理,那么实际的开发过程中,对效率和容错率上还是能帮上很大的忙!

直入主题:

很多人把他们放在一起比较,那我们首先要想到的是,他们肯定有大致相同的作用,和一些细小的区别。
先说说他们相同的作用:equals和hashCode方法都是用来判断两个对象的值是否相等,请记住这里说的相等仅仅说的是两个对象的值,和他们的引用无关

区别:

1.他们判断对象相同的方式不一样:

2.他们判断对象是否相等的准确率不一样:

为啥这样说,因为hashCode有极小概率会判断错,而equals的判断结果是百分百正确的

相信看到这里已经有朋友有疑问了,既然hashCode方法不能准确判断,那我们为什么还要用它?哈哈哈,因为我们无法忍受丢弃他的另一个优点,就是效率高,接着往下看,我们慢慢捋一捋。

先说上面的第一点:判断对象的相等的方式不一样

1.equals:重写的equals方法,比如String 的equals方法,如图:
在这里插入图片描述
他最终的目的循环判断两个对象的每一个字符是否相等,所有字符全部对应相等,那他们的值肯定也就相等了,这是equals的判断方法

hashCode的判断方法:hashCode是通过用hash算法来计算具体对象实例,得到斌返回一个hashcode值。通过比较hashcode值是否相等来判断两个对象是否相等,

相信大家看到这里是已经有点懵逼了,别急,接下来具体讲讲他的原理:

以java.lang.Object来理解,JVM每new一个Object,它都会将这个Object丢到一个Hash哈希表中去,这样的话,下次做Object的比较或者取这个对象的时候,它会根据对象的hashcode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。具体过程是这样:

  1. new Object(),JVM根据这个对象的Hashcode值,放入到对应的Hash表对应的Key上,如果不同的对象确产生了相同的hash值,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同hashcode的对象放到这个单链表上去,串在一起。
  2. 比较两个对象的时候,首先根据他们的hashcode去hash表中找他的对象,当两个对象的hashcode相同,那么就是说他们这两个对象放在Hash表中的同一个key上,那么他们一定在这个key上的链表上。那么此时就只能根据Object的equal方法来比较这个对象是否equal。当两个对象的hashcode不同的话,肯定他们不能equal.

可能经过上面理论的讲一下大家都迷糊了,我也看了之后也是似懂非懂的。下面我举个例子详细说明下。

list是可以重复的,set是不可以重复的。那么set存储数据的时候是怎样判断存进的数据是否已经存在。使用equals()方法呢,还是hashcode()方法。
  假如用equals(),那么存储一个元素就要跟已存在的所有元素比较一遍,比如已存入100个元素,那么存101个元素的时候,就要调用equals方法100次。
  
  但如果用hashcode()方法的话,他就利用了hash算法来存储数据的。
这样的话每存一个数据就调用一次hashcode()方法,得到一个hashcode值及存入的位置。如果该位置不存在数据那么就直接存入,否则调用一次equals()方法,不相同则存,相同不存。这样下来整个存储下来不需要调用几次equals方法,虽然多了几次hashcode方法,但相对于前面来讲效率高了不少。

上面开始的时候我着重说了重写的equals方法,为什么要重写呢?

因为Object的equal方法默认是两个对象的引用的比较,意思就是指向同一内存,地址则相等,否则不相等;如果你现在需要利用对象里面的值来判断是否相等,则重载equal方法。

说道这个地方我相信很多人会有疑问,相信大家都被String对象的equals()方法和"= ="纠结过一段时间,当时我们知道String对象中equals方法是判断值的,而= =是地址判断。
那照这么说equals怎么会是地址的比较呢?

那是因为实际上JDK中,String、Math等封装类都对Object中的equals()方法进行了重写。
  我们先看看Object中equals方法的源码:
  在这里插入图片描述
  我们都知道所有的对象都拥有标识(内存地址)和状态(数据),同时“==”比较两个对象的的内存地址,所以说使用Object的equals()方法是比较两个对象的内存地址是否相等,即若object1.equals(object2)为true,则表示equals1和equals2实际上是引用同一个对象。虽然有时候Object的equals()方法可以满足我们一些基本的要求,但是我们必须要清楚我们很大部分时间都是进行两个对象的比较,这个时候Object的equals()方法就不可以了,所以才会有String这些类对equals方法的改写,依次类推Double、Integer、Math。。。。等等这些类都是重写了equals()方法的,从而进行的是内容的比较。希望大家不要搞混了。

改写equals时总是要改写hashcode

java.lnag.Object中对hashCode的约定:

  1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。
  2. 如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。
  3. 如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。
    根据上一个问题,实际上我们已经能很简单的解释这一点了,比如改写String中的equals为基于内容上的比较而不是内存地址的话,那么虽然equals相等,但并不代表内存地址相等,由hashcode方法的定义可知内存地址不同,没改写的hashcode值也可能不同。所以违背了第二条约定。
    又如new一个对象,再new一个内容相等的对象,调用equals方法返回的true,但他们的hashcode值不同,将两个对象存入HashSet中,会使得其中包含两个相等的对象,因为是先检索hashcode值,不等的情况下才会去比较equals方法的。

原创文章,转载请标明出处

分享一波:程序员赚外快-必看的巅峰干货

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

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

相关文章

lol韩服游戏内设置_韩服LOL进去了还不能玩?教你如何玩韩服!

领取免费韩服LOL安全号,百度搜索韩服LOL微博关注即可!上图错误为常识性错误,LOL韩服游戏的安装文件路径有中文所导致的错误 解决方法:将安装路径里的中文改成英文即可 举例 包含中文汉字的文件夹都是错误的 Program FilesLOL韩服 …

Jdk 和 jre 的 关系和区别

Jdk 和 jre 的 关系和区别 区别: JDK:是Java Development Kit 的简称–>翻译过来就是:Java 开发工具包。是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。 JRE:是Java Runtime Environm…

OpenCV-Python入门教程7-PyQt编写GUI界面

前面一直都是使用命令行运行代码,不够人性化。这篇用Python编写一个GUI界面,使用PyQt5编写图像处理程序。包括:打开、关闭摄像头,捕获图片,读取本地图片,灰度化和Otsu自动阈值分割的功能。 使用Qt Designer…

spark 广播变量大数据_大数据处理 | Spark集群搭建及基本使用

点击蓝字关注我前面用了一篇文章详细的介绍了集群HDFS文件系统的搭建,HDFS文件系统只是一个用于存储数据的系统,它主要是用来服务于大数据计算框架,例如MapReduce、Spark,本文就接着上一篇文章来详细介绍一下Spark集群的搭建及Spa…

如何将本地项目上传到gitee

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如果以上内容对你觉得有用,并想获取更多的赚钱方式和免费的技术教程 请关注微信公众号:HB荷包 一个能让你学习技术和赚钱方法的公众号,持续更…

oracle dg 备库未设置convert参数导致ORA-01111,ORA-01110

2019独角兽企业重金招聘Python工程师标准>>> 查看trace 文件: MRP0: Background Managed Standby Recovery process started (amls) started logmerger process Sun Jan 20 07:55:53 2019 Managed Standby Recovery starting Real Time Apply MRP0: Back…

git回退历史版本无法上传_Git系列教程(二):版本库中添加文件、版本回退

Git系列教程(一):简介、安装、配置我们学习了分布式和版本控制系统的概念、Git具有的8个功能以及如何在Windows上安装Git、进行相关配置并创建版本库。Git版本库中添加文件Git 的工作就是创建和保存你的项目的快照及与之后的快照进行对比。我们编写一个readme.txt文…

nginx反向代理配置如何去除前缀

使用nginx做反向代理的时候,可以简单的直接把请求原封不动的转发给下一个服务。设置proxy_pass请求只会替换域名,如果要根据不同的url后缀来访问不同的服务,则需要通过如下方法: 方法一:加"/"** server {l…

「作文素材详解」写作必知篇:语言优美不是作文第一要求

语言优美不是作文第一要求“教孩子写作文,老师家长应该先提升自己。”“语言优美不是作文的第一要求。”“如果教孩子写漂亮的违心话,会害了他一辈子。”日前,著名作家肖复兴来到体育东路小学,与广州的一线语文教师交流&#xff0…

华为安装gsm框架_华为nova5怎么下载安装谷歌服务助手,安装GMS框架教程

看到不少的华为nova5用户喜欢这个谷歌服务助手,也就是想安装这个GMS框架,可是一直不知道如何下载安装,这个谷歌服务框架是可以在系统软件里面可以删除的一个APK程序,但现在有很多的软件和游戏需要谷歌服务的支持,那咱们…

VMware安装虚拟机并使用NAT模式连接网络

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 如果以上内容对你觉得有用,并想获取更多的赚钱方式和免费的技术教程 请关注微信公众号:HB荷包 一个能让你学习技术和赚钱方法的公众号,持续更…

PHPStudy下Apache SSL证书安装教程

一、安装SSL证书的环境 Apache安装目录:E:phpStudyPHPTutorialApache 以上为windows下测试SSL证书安装的目录,具体目录请根据自己的实际环境! 二、获取SSL证书 成功在沃通申请SSL证书后,会得到一个压缩包文件,解压后得到四个文件&…

laravel 集成采集_新版2020 Laravel采集网站程序

环境:php5.6数据库:mysql5.5集成环境软件:护卫神apache这套程序是520.ag 的网站很早的程序了是去年还是前年 应该是前年免费采集网站 但是经常挂 其实他网站挂和服务器没有多大关系 是程序没有作好优化这套程序可以大家做起来 自己用就可以了 放出去免费采集的话 网站容易死程…

详解模板方法设计模式

分享一波:程序员赚外快-必看的巅峰干货 概念 定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的重复代码全部在父类里面,不同业务的,使用抽象方法,抽取给子类进…

怎么从已有文件中挑选需要的文字重新生成新文件_CAD问题全面解答(几乎涵盖了CAD使用的全部问题)...

1.【CTrlN无效时之解决办法】众所周知CTRLN是新建命令但有时候CTRLN则出现选择面板这时只需到OP选项里调下设置操作:OP(选项)------系统-------右侧有一个启动(A显示启动对话框B不显示启动对话框)选择A则新建命令有效,反则无效2.【Ctrl键无效之解决办法】…

中国官方要求进一步加强中资商业银行境外机构合规管理

中新社北京1月22日电 (记者 王恩博)为推动在境外设有经营性机构的中资商业银行进一步优化集团合规管理体系,健全跨境合规管理机制,提高跨境合规管理有效性,实现境外机构安全稳健运行,中国银保监会22日发布《关于加强中资商业银行境…

详解:设计模式之-代理设计

分享一波:程序员赚外快-必看的巅峰干货 概念 通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理(类似于AOP)。 代理设计模式应用场景:AOP、权限控制、事务 常见代理的分类有&am…

【实时+排重】摆脱渠道统计刷量作弊行为

如今的渠道统计不仅要看精准度,更要看数据的真实性。 对App的推广业务而言,渠道监测和统计是必不可少的环节,不论以什么形式开展推广,终究都要具体落实到App的安装量、激活量等指标上。但在如今数据刷量和作假行为横行的背景下&am…

python清空idle的内容_Python IDLE清空窗口的实例

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…