为什么要重写 hashcode( ) 还要重写 equals( ) ?反之亦可问。
以map中key为对象为例子
map的结构由数组+链表+树组成。put操作代码如下图
存入key,value,实际上存入的是4个值(key的hash值,key,value,不同的key却有相同value)
非重写的hashcode是以被hashcode的数据(比如对象或者一个引用类型)的内存地址进行运算得到一个值。
重写的hashcode(一般用于对象)是以被hashcode的数据(比如对象)的某个属性值进行运算得到一个值。
非重写的equals用的是==,比较两者的引用地址是否一样。
重写的equals可以自己设定规则,一般的规则就是比较值是否一样。
在map中,假如有两个对象的属性值一致,不重写hashcode方法情况下,以对象为key进行put(暂不存入value),会出现下图情况(对象一致存入的key位置不一致)。
重写hashcode后存入map情况是下图这样(存入的key一致)
假如在上图情况中,new一个对象3,对象3的属性值和对象1,对象2一致,使用map.get(对象3)时,会出现null,如下图
这是因为尽管对象1,对象2,对象3属性一致,hash一致,但是实际存入的key值不一致的,如下图
是因为非重写的equals对比的是对象的地址,map.put的key对象属性值一样,内存地址不一样。
当重写hashcode和equals两个方法时,由于map的键不可以一样,所以map.put(p1),map.put(p2),实际put的是同一个键,这个时候用map.get(p3)才可以获取值。
假如只重写equals而不重写hashcode,会出现造成hashcode值浪费,同一个key却分布在不同的hash地址上,如下图所示
通俗点的解释
hashcode就类似小区哪栋楼
key就类似小区哪栋楼哪单元哪个门牌号
equals就是找到门牌号后需要比较里面具体的房。