继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

重写equals方法的时候为什么需要重写hashcode

Oraclea
关注TA
已关注
手记 88
粉丝 37
获赞 353

简单说下HashMap的原理,HashMap存储数据的时候,是取的key值的哈希值,然后计算数组下标,采用链地址法解决冲突,然后进行存储;取数据的时候,依然是先要获取到哈希值,找到数组下标,然后for遍历链表集合,进行比较是否有对应的key。比较关心的有两点:

  1. 无论是 put 还是 get 的时候,都需要得到key的哈希值,去定位key的数组下标;
  2. 在 get 的时候,需要调用equals方法比较是否有相等的key存储过。

HMT
  反过来,分析上面的代码,Map的key是我们自己定义的一个类,可以看到,这里没有重写equal方法,更没重写hashCode方法,意思是map在进行存储的时候是调用的Object类中equals()和hashCode()方法。为此,由控制台输出hashCode码。 HMTCode
  hashCode不一致,由此而拿不到数据。这两个key,在Map计算的时候,数组下标可能就不一致,就算数据下标碰巧一致,根据前面,最后equals比较的时候也不可能相等(很显然,这是两个对象,在堆上的地址必定不一样)。继续往下看,假如我们重写了equals方法,将这两个对象都put进去,根据map的原理,只要是key一样,后面的值会替换前面的值,接下来我们实验下:HMTEquals
  输出结果:
  instance value:1
newInstance value:2
你会发现同样的一个对象,为什么在map中存了2份,map的key值不是不能重复吗?没错,它就是存的2份,只不过在它看来,这2个的key是不一样的,因为他们的哈希码就是不一样的,可以打印看下输出的hash码确实不一样。那怎么办?只有重写hashCode()方法,更改后的代码如下:
HMTHashCode
可以看到,他们的hash码是一致的,且最后的结果也是预期的。

总结:
对于这个问题,是比较容易被忽视的,Map中存了2个数值一样的key,这个问题很严重。所以在重写equals方法的时候,一定要重写hashCode方法。
类似HashMap、HashTable、HashSet这种的都要考虑到散列的数据类型的运用。

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP