java开发——为什么要重写equals()和hashCode()方法?

【重写 equals 时为什么一定要重写 hashCode?】 阅读详情

结论:

1、重写equals()是为了实现自己的区分逻辑。

2、重写hashCode()是为了提高hash tables的使用效率,以及和equals()保持一致(看下面hashcode的第三点)。

举例:

1、String重写Object的equals方法

2、HashSet是如何保证存储的元素不同的?

 

首先明白这两个方法是什么来的?

equals()和hashCode()是Object的两个方法。作用有两个:

1、区分两个Object

2、给子类重写,让子类去实现自己的区分逻辑。

看下Object的源码是如何区分两个Object的。

public boolean equals(Object obj) {
     return (this == obj);
}

可以看出除了==this,否则两个对象不相同。

对于hashCode,源码注释中这样解释的:

1、它是一个代表Object的整数int值,它有利于哈希表的存储使用。(重要)

2、无论何时调用同一对象此方法,返回值都应是相同的。(equals用到的比较信息没有被修改的情况下)

3、如果equals()方法确定了两个对象相等,则这两个对象的hashCode必须返回相同的值(这点就可以决定重写equals()方法就必须重写hashCode方法了)

4、如果equals()方法确定了两个对象不相等,这个两个对象的hashCode还是有可能相等的。但是我们强烈建议不同的对象应该有着不同的hashCode,这样可以提高hash tables的使用效率。

综上,为什么要重写equals()和hashCode()方法的原因有两个:

1、重写equals()是为了实现自己的区分逻辑。

2、重写hashCode()是为了提高hash tables的使用效率。

下面是举例:重写的重要性

例子1:String重写Object的equals方法,源码如下:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = count;
            if (n == anotherString.count) {
                int i = 0;
                while (n-- != 0) {
                    if (charAt(i) != anotherString.charAt(i))
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

public int hashCode() {
        int h = hash;
        if (h == 0 && count > 0) {
            for (int i = 0; i < count; i++) {
                h = 31 * h + charAt(i);
            }
            hash = h;
        }
        return h;
    }

可以看出在重写equals()和hashCode()方法时,字符串中的每一个字符都用上了。这样,"abc"和"adcd"的hashCode肯定不相同。"abc".equals("abc")返回true是我们要的结果,符合我们区分逻辑。而不是像Object的equals方法那样“this == obj”引用相等才相同。所以String需要重写Object的equals方法。

例子2:HashSet是如何保证存储的元素不同的?

看下add方法,源码如下:

private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();

public boolean add(E e) {
     return map.put(e, PRESENT)==null;
}

可以看出,HashSet底层是依靠HashMap实现的,而我们知道,HashMap的键值是不可以重复的(可以为null)。重点来了,HashMap保证键值不重复就是依靠对象的equals()和hashCode()方法。

看HashMap的put方法部分伪代码:

1、key是新加入的对象
2、hash是key的哈希值
3、e是哈希表中的每一个元素
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
   1、新值覆盖旧值(这个都是同一个Object PRESENT = new Object();)
   2、返回旧值
}
否则新增新的结点存储新值。

可以看出,在HashMap新增key-value的时候,如果hashCode和equals都相同,HashMap不会新增新的结点存储新值。而是在原来的key上覆盖掉value值。那么对于HashSet来说,也就是没有新增元素,因为HashSet的元素来源于HashMap的key集合。

 也就是说HashSet保证存储的元素的不同,是通过equals()和hashCode()方法来保证的。这就是为什么我们要重写equals()和hashCode()方法的重要原因之一。

补充:对于equals不相同而hashCode相同的元素集合,在哈希表中会以链表或者红黑树的形式储存!

 

觉得有用的老铁们赞一下,谢谢!

5分钟搞定!用ZLMediaKit+GB28181搭建低成本外网视频监控(含避坑指南) 本文详细介绍了如何利用开源ZLMediaKit流媒体服务器与国标GB28181协议,快速搭建低成本、可外网访问的企业级视频监控系统。文章提供了从服务端部署、设备配置到外网访问优化的完整实战指南,并重点分享了网络配置、性能调优及常见问题的避坑方案,帮助用户实现高清视频流的稳定推送与多格式播放。 阅读详情

相关推荐

思科路由器IPv6各种路由协议配置

思科路由器IPv6路由协议配置:1、静态路由配置;2、默认路由配置;3、RIPng路由配置;4、OSPFv3路由配置。

weixin_41687096的博客 6544

为什么要重写hashCode()和equals()

从源码的角度,介绍hashCode()和equals()函数的作用,解释为什么需要重写,什么时候需要重写,具体应该怎么重写。

LYQ20010417的博客 4904

MATLAB机械臂轨迹规划:在关节空间中生成多项式轨迹以及 jtraj函数(内容超详细讲解)

matlab机器人仿真,关节空间多项式轨迹生成

qq_40969179的博客 1万+

通俗解释——为什么要重写hashCode()和equals()方法

目录 一、通俗解释 二、案例说明 三、总结 一、通俗解释 无论是对于初学者还是面试,这个问题都是一个经典。我们这里使用通俗易懂也就是俗称的“说人话”来解释为什么要重写hashCode()和equals()方法。 首先,以HashMap为例,我们简单了解一下其内部结构。HashMap底层采用了数组+链表的构造,其中jdk1.8开始还使用了红黑树。简图如下: HashMap中每个单元位置都是一个Entry,又称为桶(bucket),其中jdk1....

flesaca的博客 2722

Qt中多线程的使用(一)

我们要实现的是读取大文件qtgui.index的内容加入文本框中。 很容易想到的方法: QFile* file = new QFile("E:\qtgui.index"); file-&gt;open(QIODevice::ReadOnly); QTextStream *stream = new QTextStream(file); while(!st...

yao5hed的专栏 1万+

Linux系统下奥比中光Astra Pro相机SDK部署与避坑指南

本文详细指导了在Linux系统下部署奥比中光Astra Pro深度相机SDK的全过程,涵盖系统准备、SDK安装、设备权限配置及常见问题排查。重点解析了USB设备规则配置这一关键步骤,并提供了Python与C++项目的集成方法,旨在帮助开发者快速完成相机配置,避免常见陷阱。

weixin_28455801的博客 300

为什么要同时重写equals方法和hashCode方法(详解)

首先,我们在作比较时,通常调用equals方法来比较(这里指Object类中的equals方法),比较俩个对象的地址值是否一样,地址值相同,则俩个对象相同。地址值不同,则俩个对象不同。 在这里,其实有个问题:当我们向一个集合中插入了一个对象,并且这个集合中有几万条数据,那我们还和之前一样,调用它的equals方法来比较俩个对象是否相等嘛? 当然,可以是可以,但效率必然是个问题。那么在考虑效率的情况下,如何去比较俩个对象是否相等呢,这个时候就用到了hashCode方法。hashCode方法是按照一定的规则将与

小情歌的博客 1万+

机器学习(三) ----------线性回归算法(梯度下降+正则化)

线性回归算法在机器学习中具有核心地位,它以其简单性和直观性为基础,为理解数据间的关系提供了基本框架。作为许多复杂算法的基础,线性回归不仅用于预测目标变量,还用于解释自变量对目标的影响。同时,它也是机器学习入门的经典算法,对于推广机器学习知识和技术具有重要意义。

2301_77539454的博客 1868

hashCode() 方法有什么作用呢?

一.引言 首先 hashCode() 方法被设计在 Object 类中,说明是希望所有的对象都能实现该方法,该方法是会返回一个对应于当前对象的一个整数,之所以所有对象都实现该方法是为了将来对象在查找时变得快捷。 Java中的集合类 hashMap、hashSet 底层的实现都是哈希表,之所以采用哈希表,是因为他能克服链表和二叉树等数据结构在查询上的低效率问题,哈希表的存储就是根据对象的哈希值,以...

HU1656的博客 2670

ASPICE学习笔记

ASPICE的全称是Automotive SPICE。

汽车电子软件领域知识分享 1355

点云焊缝提取

本文介绍了一个基于PCL库的点云处理流程,包含三个核心模块:MLS平滑处理通过多项式拟合修正点云位置;差异提取通过双向匹配定位源/目标点云的非重叠区域;统计过滤剔除离群噪声点。该流程采用"平滑-筛选-净化"的通用思路,将复杂算法封装为可配置接口,实现了工业级点云预处理。文章重点分析了各模块的原理、PCL接口调用及参数设计逻辑,同时指出参数调优、算法扩展等深入探索方向,展现了PCL在点云处理中的模块化优势与实用价值。

weixin_45196569的博客 250

JAVA中重写equals()方法的同时要重写hashcode()方法

object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true; 注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定...

测试0901-1 131

华为OD机试真题 新系统 2026-04-19 C语言 实现【8位LED控制器】

有一个8位LED控制器,包含8个LED灯(编号0-7),初始状态全灭,用8位二进制表示为:00000000。控制器可以接收以下三种指令: Lx:L表示点亮操作,x表示LED的编号(0一7),操作得到的结果是:点亮第x个LED灯,把状态设为1。 Dx:D表示熄灭操作,x表示LED的编号(0-7),操作得到的结果是:熄灭第x个LED灯,把状态设为0。 Tx:T表示切换操作,x表示LED的编号(0-7),操作得到的结果是:切换第x个LED灯的状态,若状态为0则变为1,为1则变为0。 现在给定一组指令字符串(0<

MISAYAONE的博客 148

equals方法与hashcode方法的重写

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

SuYuewu的博客 1911

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

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

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

为什么重写 equals 还要重写 hashCode 方法?

(1)如果两个对象的 hashCode值相等的情况下,对象的内容值不一定相等(hash碰撞问题) (2)如果使用 equals 方法比较两个对象内容值相等的情况下,则两个对象的hashCode值一定要相等

金鳞踏雨 855

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

为什么重写equals()一定要重写hashCode()呢

为什么重写equals()一定要重写hashCode()呢?

qwwee123的博客 190

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【JavaSE】重写equals()和hashCode()

重写equals()方法实现比较对象的内容是否相等 为了保证“用equals()方法判断相等的对象,hashCode()也相等”,必须重写hashCode()方法。

weixin_42904738的博客 243

Java面试-hashCode() 和 equals() 为什么必须成对重写

场景推荐做法自定义类必须成对重写equals()和hashCode()字段选择使用final、不可变字段作为依据代码生成用 IDE 或 Lombok 自动生成比较内容用安全处理null生成哈希用集合使用确保重写后,对象能在HashSetHashMap中正常工作equals()相等 ⇒hashCode()必须相等。hashCode()是equals()的“向导”,不能失联。用和,少写 bug。

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

hashcode是什么意思_为什么重写 equals() 方法,一定要重写 hashCode() 呢?| HashMap

首先我们有一个假设:任何两个 object 的 hashCode 都是不同的。 那么在这个条件下,有两个 object 是相等的,那如果不重写 hashCode(),算出来的哈希值都不一样,就会去到不同的 buckets 了,就迷失在茫茫人海中了,再也无法相认,就和 equals() 条件矛盾了,证毕。 撒花~~ 接下来我们再对这两个方法一探究竟: 其实 hashCode() 和 equ...

weixin_39621044的博客 189

java开发:为什么重写Object的equals()必须要重写hashCode()

在开始讨论标题这个问题之前我们先搞清楚几个概念: 1.基本数据类型和引用类型 我们知道java数据类型一般有俩大类,第一种基本数据类型,第二种引用类型。基本数据类型是没有引用这个概念的,例如 int a = 1,a 是直接存放在堆栈中直接指向它的内容。而平时我们使用的User user = new User(),我们创建的对象是保存在堆中,user是引用类型,它保存在堆栈中,保存的内容是User...

一个程序员-二白的博客 524

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

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

南瓜灯cc 3万+

为什么重写equals()就一定要重写hashCode()方法?

如果涉及使用对象作为key,那么key的对象都必须实现hashCode和equals方法。hashCode和equals方法持续自根类Object,若是你用自定义的类算作key的话,就需要同时覆写equals办法和hashCode方法,因为我们java的集合中判断两个对象是否相等,是根据hashCode和equals这个俩个方法。规则是先判断两个对象的hashCode是否相等,如果不相等,认为两个对

sixingmiyi39473的博客 7838

为什么重写equals()时一定要重写hashCode()?

equals()的时一定要重写hashCode 如:String a = "123456",String b = "123456",在 equals 方法看来,两个字符串的内存地址不相等,所以仍然会判定为不相等,所以需要去重写 equals 方法,只有重写了equals 方法之后,我们再去判断 a 和 b,此时判断结果就会相等。equals()和 hashCode()是 Object 类中的两个基础方法,Object 中的 equals( )和hashCode( ),使用==判断,即比较两个对象的地址值。

m0_64422133的博客 2571

关于为什么要重写hashCode()方法和equals()方法及如何重写

我想写的问题有三个: 1、首先我们为什么需要重写hashCode()方法和equals()方法 2、在什么情况下需要重写hashCode()方法和equals()方法 3、如何重写这两个方法 ********************************************************************* 第一个问题:为什么需要重写hashCode()方法和equ

jing_bufferfly的博客 1万+

为什么要重写equals()方法 和 hashCode()方法

Equals 和 HashCode方法是属于Object的,所以每个对象都有自己的equals 和 HashCode方法 为什么要重写equals()方法 1、equals()默认是比较的对象地址(源码见下图),而不是比较的对象的属性值,不符合我们的期望。 特别指出八大包装对象(如int,float等对应的包装类)和String类已重写了equals和hashcode方法,默认比较的是值 ...

【小石头的茅坑】 71万+

java重写equals()方法和hashCode()方法

引用块内容 1.equals()方法和hashCode()方法是什么? equals()和hashCode()都是是Java中万物之源Object类中的方法; equals方法用于比较两个对象是否相同,Object类中equals方法的实现是比较引用地址来判断的对象是否是同一个对象,通过覆盖该方法可以实现自定义的判断规则; hashCode是jdk根据对象的地址或者字符串或者数字计算...

潘超博客 2万+
上一篇: java开发——enum枚举单例的使用
下一篇: java开发——Cloneable接口、clone()方法和深浅拷贝
river66
博客等级 码龄8年 76粉丝 108原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值