HashMap底层的运用算法
索引算法
int index = Hash(key.Hashcode) & (table.length - 1)
算法解析
Hash --> Java的Hash算法(固定算法)
key.Hashcode --> 根据每个传入的key算出它的HashCode值
table.length --> 数组的长度
& --> 二进制运算(运算时,有0为0)
举例一
Hash(key.Hashcode) 得出的值为 01010101
table.length 为16
table.length - 1 得出的值为 15 --> 00001111
计算:
01010101
&
00001111
结果:
00000101
为
5
结论:
该key应放入第5个索引中
举例二
Hash(key.Hashcode) 得出的值为 01010101
table.length 为5
table.length - 1 得出的值为 4–> 00000100
(0,1,2,3,4)
计算:
01010101
&
00010000
通过计算,我们可以算出这个数组,我们除了可以索引0和4,其他索引我们都用不到
结论
因为算法中由于key的值一直在产生变化,而Hash和table.length是不变的
为了保证每一个索引都能有元素放入,table.length必须为2的n次方,这样在长度-1后,二进制才能保证后面几位都是1
所以HashMap的每一次扩容的长度都是2的n次方
大数据衍生
那么我们就要思考一个问题,是不是所有和key有关的hash都用的&运算呢?
其实并不是,尤其是在大数据的kafka中
kafka中分区数往往设置为奇数
那么我们怎么保证每一个topic都能存入key呢
在这里显然再用&运算就不合适了,我们就要采用对key的HashCode进行除余的方式,最后得出的余数才是我们key所要去的最终topic号