本文接上篇【小话HashMap系列 NO.1】探寻那些不为人知的隐秘角落
我是小月,我本来在兵工厂的椅子上好好坐着,却来了一位女郎直接坐在了我腿上。
“你抢了我的位置… …”她这样说。
hash冲突
进入兵工厂时,工作人员给我们分发了一块电子显示屏,上面显示着我们的座位号,我的座位号是 ‘6’ 。
但她的显示屏上也写着 ‘6’,现在一个椅子分配给了两个参观者,这可怎么办?
”要不你先起来,我让你?“ 腿上坐着一位女郎,我极度不自在,还是把位置让给她坐好了。
“本来就是我的座位!”她横了我一眼,摇着脚尖,翘着的二郎腿没有放下去的意思。她赖在我腿上啦!不过她身上的味道闻起来真的好香呀。
这样下去也不是办法,毕竟我是一个血气方刚的‘男对象’!没办法,只好向旁边座位的老爷爷求助。
“Amia,你帮帮我。”
刚才还给我热心讲解兵工厂规则的老爷爷,转眼居然已经闭目养神起来,只是幽幽地说上了一句,“这位置,还真是这位小兄弟的。”
这说的叫什么话?这不是火上浇油吗!老爷爷真是的!
“不用不用,我让给你坐就是了。”我准备起身,偏偏女郎一只手在这时按在我肩上,不让我站起来。
“好好坐着,我们的位置你说了可不算,在工作人员过来之前,你最好老实坐着别乱动。”她轻哼了一声,“我不喜欢我的板凳晃来晃去!”
她说什么?她把我当她的板凳了!希望工作人员早点来吧,给别人当凳子真不是一件舒服的事,除非她温柔一点还差不多。
等了一小会儿,终于有工作人员注意到我们这边的异常,快步走了过来。
“你们的座位号冲突了?” 工作人员问。
“是。我们这种情况是采用头插法处理吧?偏偏旁边的老爷子有反对意见。”女郎很不满地说道。
“抱歉。”工作人员拿出《兵工厂说明手册》翻看后,说道:“您说的是1.7之前的版本了,如今我们是全新升级版1.8,所以这一块的规则有调整。现在我们采用尾插法处理座位号的冲突。”
“改了?”女郎晃动的鞋尖停止下来,顿了一秒才说道,”行吧,那你帮我搬一把椅子过来吧。“
工作人员转身搬椅子去了。
“对不起,是我弄错了。我向你道歉。”女郎站起来,冲我歉意一笑。
她突然温柔起来,让我有些不适应,连忙回道:“没关系”。
工作人员搬来椅子,她在我前面坐了下来,现在我们的座位是这样的。
呼,总算处理掉了大麻烦,不过她们说的头插法和尾插法究竟是什么意思?我想着《兵工厂说明手册》应该会有答案。
“嘿嘿,小兄弟,你可错过了一段姻缘呐~” Amia不知道什么时候结束了闭目养神,小声地在我耳边说着。我转过头就看见了他纯洁的笑容。
呸,老不正经的!我在心里得出结论。不行,我得赶紧转移话题。
“她们说的头插法和尾插法是什么意思呢?”我问道,我可不想他再继续刚才的话题。
刚好我也翻到了手册上的说明:
哈希冲突:参观者座位号重复。
解决:数组+链表的方式处理。
特别说明:jdk1.7之前的版本,新增元素到链表中使用头插法;jdk1.8之后的版本,链表使用尾插法。
Amia挺直了后背,又恢复了一本正经的老爷爷模样,他解释说:“还记得我给你讲的,咱们座位的计算方式吧。调用我们自身的hashcode()方法获取一个int值,再将int值对数组长度进行取模运算。我写了两个例子,你看看。”
他递过来一张纸片,上面写着:
6%16 = 6;
22%16 = 6;
“看明白了吧,既然是取模运算,那我们的座位号肯定会冲突,这种情况也称作哈希冲突。
而解决的方案也就是采用数组+链表的方式处理咯。"
看完这些,我顿时明白了。Amia正经起来果然还是有货的嘛。
数组下标计算方式详解
“之前我只是给你讲了一个简易版本的下标计算,现在,我仔细给你讲解一下。”Amia问,”你知道位运算吗?“
我摇摇头。
“很简单,位运算就是将十进制转换成二进制来进行运算的方法,在我们的世界里,位运算是效率最高的一种运算方式。我简单给你介绍两种,然后你才能理解我们的座位号到底是怎么计算出来的。”
异或运算 ^
结果: 52 ^ 68 = 112
与运算&
结果 : 52 & 68 = 4
“现在你已经学会‘异或’运算和‘与’运算了,翻到《兵工厂说明手册》的附页,上面有座位号计算的详细公式。”
Amia示意我往后翻,我赶紧打开附页,找到了座位号计算公式:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
“我用字符串 ‘I am the moon’ 来给你完整的解释一遍,认真看图。”Amia开始在纸上画起来。
"以上是调用hash()方法获取的结果,座位号(数组下标)的计算依赖上面的结果,具体的计算公式看这里。”Amia翻了一页,指给我看。
tab[i = (n - 1) & hash]
i :座位号
n: 数组长度
hash:调用hash()方法获取的结果值
他继续在纸上画着。
“现在明白了吧?” Amia长长呼出一口气,笑着问道。
“明白了。”不得不说,他讲解得很清楚,还补充了我不会的位运算方面的知识。
我本来以为,我已经知道了所有座位号的计算规则,毕竟这套规则已经非常复杂了。但Amia接下来的一句话,让我了解到事情没有这么简单。
Amia说:“如果是1.7之前的版本,讲解第一次的规则就够了。但是现在是1.8的新版,一切都大不同了。”
我脱口而出:“扩容时座位号的计算规则不同?”
Amia露出一个带有深意的笑容,“累了,喝口水。你要学的东西还多着呢,如果我没猜错的话,兵工厂就要拉响【贪吃蛇】警报了,等着看吧… …”
分隔线
贪吃蛇。【噗~】,你能猜到【贪吃蛇】警报是什么意思吗?下一篇揭晓。
To be continued… …
任何美好的事情都值得分享,关于生活,关于工作(认真工作可以让生活更美好)。如果喜欢我的文章,可以关注我的公众号【猿月亮】和我互动哦。