Java—hashCode、equals
创始人
2024-03-18 10:42:04
0

文章目录

  • hashCode()
    • 介绍hashCode()
    • hashCode方法作用
    • 为什么要有hashCode()?
  • equals()
    • equals()作用?
    • 为什么重写equals方法必须重写hashcode方法?
    • 128陷阱?
  • equals和hashCode的关系

———————————————————————————

hashCode()

介绍hashCode()

hashCode()定义在JDK的Object中,这就意味着Java中的任何类都包含有hashCode()方法。hashCode()的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数,作用是确定该对象在哈希表中的索引位置。

散列表存储的是键值对(key-value),它的特点是:能根据"键"快速的检索出对应的"值”。(可以快速找到所需要的对象)

hashCode方法作用

作用:获取哈希值,哈希值的计算利用的是对象在堆中开辟空间的内存地址

为什么要有hashCode()?

以"HashSet如何检查重复"为例子说明为什么要有hashCode:

当把对象加入HashSet中时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会跟其他已经加入的对象的hashcode值作一个比较,如果没有相等的hashcode值,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,就会调用equals()方法来检查hashcode值相等的对象是否真的相同。如果两个对象相同,HashSet就不会让它加入。如果不同的话,就会把它重新散列到其他位置。这样我们就大大减少了 equals的次数,相应就大大提高了执行速度。

equals()

Object类的equals方法,底层是使用“==”来实现,

  • 如果比较的两个变量是基本类型,就是在比较其值是否相等。
  • 如果比较的两个变量是引用类型,就是在比较其地址是否相等。

注:其实基本类型不用equals方法
在这里插入图片描述

  • this代表当前对象,谁调用这个方法,this代表谁

比较的时候java会重写equals方法,因为使用equals方法会新申请空间,所以地址肯定不同
例:
以下返回肯定是false,因为地址不同
在这里插入图片描述
——>所以使用equals:
重写后的equals方法源码:
在这里插入图片描述
注:980行的判断条件 + 981行的String anotherString = (String)anObject;-------判断父类类型是不是子类的,是子类的才能强转为子类

equals()作用?

(1)equals()方法用来对两个变量的值进行比较。

equals()只能针对引用数据类型;equals()来源于Object类(object类是所有类的父类),object类当中的equals() 是用 == 比较的地址是否相等;String 类当中的equals()是对Object类当中的equals()的重写;String 类当中的equals(),首先进行的是地址比较,当两个字符串的地址不同时,在进行值的比较。包装类当中的equals(),对数据进行一个拆箱,用==进行值的比较。至于为什么要拆箱,其实是因为要避免128陷阱。

(2)注意事项: 如果要重写equals()方法,一定要重写hashCode()方法。

①: 0bject 中hashCode()是根据对象的存储地址转换而形成一个int类型的哈希值,equals()则进行地址判断
②: HashMap中需要hashCode()和equals()两个相结合使用,当存储数据的时候, key相同,后面的数据的会覆盖前面的数据,key需要用equals()去判断, value 的存储位置需要根据 key 的 hashCode()进行判断。

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

  • 首先equals在object类里的作用是比较两个引用指向的是否是同一个对象, 也就是两个对象的地址是否相同
  • 但是我们在实际开发过程中,这种开发方式往往不满足我们的需求,比如我们有一个person类,我们的需求可能是当一个人的年龄和姓名和性别都相同时,我们就认为这是同一个人
  • 所以我们需要重写equals方法来自行决定两个对象相等的判别方式 , 但是在hashSet或者说hashMap的底层判断两个对象是否相同是需要hashcode和equals同时来决定的(hashset的底层是hashmap)
  • 所以如果我们只重写了equals但是没有重写hashcode,我们在用hashset去重的时候,其底层就会认为这是两个不同的对象,去重就会失败。

128陷阱?

两个基本类型的包装类用==进行数据比较,如果值的范围在-127~128之间,那么返回true,如果在这个范围之外,返回false;

至于为什么会出现这种情况呢?
—>对于非new出来的包装类对象,以Integer为例,Integer当中,有一个方法,将基本类型转换为Integer类型,在代码当中,一定范围内返回的数据和范围外返回的数据不同,这个范围定义的是-128127,值不在-128127之间的话,是在堆内存开辟新的内存空间存储值,Integer num3 = 200和Integer num4 = 200相当于在堆内存开辟了两块内存空间,两个内存空间都存储200这个值,而==比较的是地址,所以返回false。

equals和hashCode的关系

在这里插入图片描述

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...