快来,我悄悄的给你说几个HashCode的破事。 (5)

简介: 快来,我悄悄的给你说几个HashCode的破事。 (5)

HashMap put 方法执行的时候,用的是 equals 方法判断当前 key 是否与表中存在的 key 相同。


我们这里没有重写 equals 方法,因此这里返回了 false。


所以,如果我们 hashCode 和 equals 方法都没有重写,那么就会出现下面示意图的情况:


image.png


如果,我们重写了 hashCode,没有重写 equals 方法,那么就会出现下面示意图的情况:


image.png


总之一句话:在 HashMap 中,如果用对象做 key,那么一定要重写对象的 hashCode 方法和 equals 方法。否则,不仅不能达到预期的效果,而且有可能导致内存溢出。


比如上面的示例,我们放到循环中去,启动参数我们加上 -Xmx10m,运行结果如下:


image.png


因为每一次都是 new 出来的 student 对象,hashCode 都不尽相同,所以会不停的触发扩容的操作,最终在 resize 的方法抛出了 OOM 异常。


奇怪的知识又增加了


写这篇文章的时候我翻了一下《Java 编程思想(第 4 版)》一书。


奇怪的知识又增加了两个。


第一个是在这本书里面,对于 HashMap 里面放对象的示例是这样的:


image.png


Groundhog:土拨鼠、旱獭。


Prediction:预言、预测、预告。


考虑一个天气预报系统,将土拨鼠和预报联系起来。


这 TM 是个什么读不懂的神仙需求?


image.png


幸好 why 哥学识渊博,闭上眼睛,去我的知识仓库里面搜索了一番。


原来是这么一回事。


在美国的宾西法尼亚州,每年的 2 月 2 日,是土拨鼠日。


根据民间的说法,如果土拨鼠在 2 月 2 号出洞时见到自己的影子,然后这个小东西就会回到洞里继续冬眠,表示春天还要六个星期才会到来。如果见不到影子,它就会出来觅食或者求偶,表示寒冬即将结束。


这就呼应上了,通过判断土拨鼠出洞的时候是否能看到影子,从而判断冬天是否结束。


这样,需求就说的通了。


image.png


第二个奇怪的知识是这样的。


关于 HashCode 方法,《Java编程思想(第4版)》里面是这样写的:


image.png


我一眼就发现了不对劲的地方:result=37*result+c。


前面我们才说了,基数应该是 31 才对呀?


image.png


作者说这个公式是从《Effective Java(第1版)》的书里面拿过来的。


这两本书都是 java 圣经啊,建议大家把梦幻联动打在留言区上。


《Effective Java(第1版)》太久远了,我这里只有第 2 版和第 3 版的实体书。


于是我在网上找了一圈第 1 版的电子书,终于找到了对应描述的地方:


image.png


可以看到,书里给出的公式确实是基于 37 去计算的。


翻了一下第三版,一样的地方,给出的公式是这样的:


image.png


而且,你去网上搜:String 的 hashCode 的计算方法。


都是在争论为什么是 31 。很少有人提到 37 这个数。


其实,我猜测,在早期的 JDK 版本中 String 的 hashCode 方法应该用的是 37 ,后来改为了 31 。


我想去下载最早的 JDK 版本去验证一下的,但是网上翻了个底朝天,没有找到合适的。

书里面为什么从 37 改到 31 呢?


作者是这样解释的,上面是第 1 版,下面是第 2 版:


image.png


用方框框起来的部分想要表达的东西是一模一样的,只是对象从 37 变成了 31 。


而为什么从 37 变成 31 ,作者在第二版里面解释了,也就是我用下划线标注的部分。


31 有个很好的特许,即用位移和减法来代替乘法,可以得到更好的性能:


31*i==(i<<5)-1。现代的虚拟机可以自动完成这种优化。


从 37 变成 31,一个简单的数字变化,就能带来性能的提升。


个中奥秘,很有意思,有兴趣的可以去查阅一下相关资料。


真是神奇的计算机世界。


好了,这次的文章就到这里啦。


才疏学浅,难免会有纰漏,如果你发现了错误的地方,可以在留言区提出来,我对其加以修改。


感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。


我是 why 哥,一个被代码耽误的文学创作者,不是大佬,但是喜欢分享,是一个又暖又有料的四川好男人。


欢迎关注我呀。


目录
相关文章
|
算法 C语言
二分查找——我欲修仙(功法篇)
二分查找——我欲修仙(功法篇)
86 0
|
安全 Java
快来,我悄悄的给你说几个HashCode的破事。 (2)
快来,我悄悄的给你说几个HashCode的破事。 (2)
141 1
快来,我悄悄的给你说几个HashCode的破事。 (2)
想过七夕?->女朋友陪你玩游戏(C)(上)
三子棋 七夕到了,没有女朋友怎么办?没事~ 写一个小游戏,让女朋友陪你玩三子棋~
想过七夕?->女朋友陪你玩游戏(C)(上)
想过七夕?->女朋友陪你玩游戏(C)(中)
在一定数值范围内,游戏随机生成一个数字,玩家输入比随机数大的数字时,程序会提醒,数值大于目标数,反之亦然。通过不断试错,最终找出目标数字。此游戏可以重复玩。
想过七夕?->女朋友陪你玩游戏(C)(中)
想过七夕?->女朋友陪你玩游戏(C)(下)
七夕到了,没有女朋友怎么办?没事~ 写一个小游戏,让女朋友陪你玩扫雷~
想过七夕?->女朋友陪你玩游戏(C)(下)
|
算法 Java
工作三年,小胖连 HashMap 源码都没读过?真的菜!(上)
工作三年,小胖连 HashMap 源码都没读过?真的菜!
工作三年,小胖连 HashMap 源码都没读过?真的菜!(上)
|
存储 算法 安全
工作三年,小胖连 HashMap 源码都没读过?真的菜!(下)
工作三年,小胖连 HashMap 源码都没读过?真的菜!
工作三年,小胖连 HashMap 源码都没读过?真的菜!(下)
|
测试技术
快来,我悄悄的给你说几个HashCode的破事。 (4)
快来,我悄悄的给你说几个HashCode的破事。 (4)
95 0
快来,我悄悄的给你说几个HashCode的破事。 (4)
|
Java 测试技术
快来,我悄悄的给你说几个HashCode的破事。 (3)
快来,我悄悄的给你说几个HashCode的破事。 (3)
93 0
快来,我悄悄的给你说几个HashCode的破事。 (3)
|
算法 Java
快来,我悄悄的给你说几个HashCode的破事。 (1)
快来,我悄悄的给你说几个HashCode的破事。 (1)
121 0
快来,我悄悄的给你说几个HashCode的破事。 (1)
下一篇
无影云桌面