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

本文详细讲解了equals方法和hashCode在Java中的作用,解释了为何重写equals时需同时重写hashCode,以及为何在HashSet中未重写equals导致的问题。重点讨论了如何通过重写hashCode解决对象去重问题,以及为什么遵循equals和hashCode一致性原则。
摘要由CSDN通过智能技术生成

目录

1、equals方法

2、hashcode方法

3、hash算法

4、重写equals方法

5、重写HashCode方法


在每个类中,重写equals方法的时侯,一定要重写hashcode方法。

Object类中的equals方法,底层是通过==来进行比较,所以比较的是对象的内存地址

1、equals方法


2、hashcode方法

Java中的hashCode方法就是根据一定的规则与对象相关信息(例如对象的存储地址,对象的字段等)映射成一个数值,这个数值就被称为散列值 

3、hash算法


就是将hashcode的得到的随机数(散列值),映射成固定长度的值

Java中规定:

(1)如果两个对象通过equals方法比较是相等的,那么它们的hashCode方法结果值也是相等的。

(2)如果两个对象通过equals方法比较是不相等的,那么它们的hashCode方法结果值不一定不相等。

很多情况下,我们比较对象并不需要比较对象的地址,而是只要是同一个类的不同对象,成员属性值相同,我们就认为是同一个对象

 上图所示,没有重写equals方法的情况下,这里的比较返回的是false(因为比较的是堆中的内存地址)。

4、重写equals方法

但是两个对象是同一个类,而且成员变量的值都是相同,所以我们可以认为是同一个对象,为了达到这个效果,就必须重写equals方法,让他们比较的是类的类型和成员变量的值

这里发现equals比较的是对象的成员变量的值了,并不是比较的内存地址,但是两个对象的hashcode还是不相同,这就会导致如下问题

 HashSet有一个特性就是不能允许相同的值的存在,我们car1和car2对于我们来说就是同一个对象(同类型,同值),那么为什么会存在这个问题呢?

我们知道HashSet底层是通过HashMap来实现的,HashMap的key就是我们存入HashSet中的值,而value是一个固定值(一个静态的Object对象,并不需要去管),而HashMap的底层是通过数组+链表+红黑树(>=1.8),hashmap底层在计算数组下标位置就是使用的hashcode去实现的hash算法,所以如果hashcode的值不同,计算出来的数字下标位置就有可能不同,所以就将car1和car2放在了不同的数组的位置,所以并不会进行覆盖(正常情况下如果hashcode相同,得到相同的数组下标位置,还需要进行equals来比较是否是同一个元素),所以这就导致Hashset不能起到去重的作用

所以这里也是我们需要重写HashCode方法的原因

5、重写HashCode方法

 

 这里可以看到,重写HashCode方法之后,两个实例对象的hashcode的值也就是相同的,HashSet也就能起到了去重的效果

所以Java中规定,一般重写equals方法就要重写HashCode方法,也是为了保证在不同场景下使用不会出错

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值