为什么要重写 hashcode( ) 还要重写 equals( ) ?反之亦可问。

以map中key为对象为例子

map的结构由数组+链表+树组成。put操作代码如下图

不重写hashcode和equals出现的问题
存入key,value,实际上存入的是4个值(key的hash值,key,value,不同的key却有相同value)

非重写的hashcode是以被hashcode的数据(比如对象或者一个引用类型)的内存地址进行运算得到一个值。

重写的hashcode(一般用于对象)是以被hashcode的数据(比如对象)的某个属性值进行运算得到一个值。

非重写的equals用的是==,比较两者的引用地址是否一样。

重写的equals可以自己设定规则,一般的规则就是比较值是否一样。

在map中,假如有两个对象的属性值一致,不重写hashcode方法情况下,以对象为key进行put(暂不存入value),会出现下图情况(对象一致存入的key位置不一致)。

不重写hashcode和equals出现的问题
重写hashcode后存入map情况是下图这样(存入的key一致)

不重写hashcode和equals出现的问题

假如在上图情况中,new一个对象3,对象3的属性值和对象1,对象2一致,使用map.get(对象3)时,会出现null,如下图
不重写hashcode和equals出现的问题
这是因为尽管对象1,对象2,对象3属性一致,hash一致,但是实际存入的key值不一致的,如下图
不重写hashcode和equals出现的问题

是因为非重写的equals对比的是对象的地址,map.put的key对象属性值一样,内存地址不一样。

当重写hashcode和equals两个方法时,由于map的键不可以一样,所以map.put(p1),map.put(p2),实际put的是同一个键,这个时候用map.get(p3)才可以获取值。

假如只重写equals而不重写hashcode,会出现造成hashcode值浪费,同一个key却分布在不同的hash地址上,如下图所示
不重写hashcode和equals出现的问题

通俗点的解释

hashcode就类似小区哪栋楼

key就类似小区哪栋楼哪单元哪个门牌号

equals就是找到门牌号后需要比较里面具体的房。

如果解释的不对或者有疑问的地方,请务必评论提出来!在下一定改正或者答疑。

这是一个没什么人看,但是还想贴出来的公众号二维码

不重写hashcode和equals出现的问题

相关文章: