前几天面试问道HashMap实现原理,我巴拉巴拉一通说。然后面试官问我扩容时为什么要左移1位。我沉思了很久,没回答上来。时候查阅资料总结下:
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。我们上面也讲到了过了,Hash 值的范围值-2147483648到2147483647,前后加起来大概40亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个40亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“ (n - 1) & hash”。(n代表数组长度)。这也就解释了 HashMap 的长度为什么是2的幂次方。
HashMap put() 方法在取数组下表时用到了这个算法: (n-1) & hash 这里解释是 hash 对 数组长度取模。这里就有规定了,前提必须是hsas 是2的整数幂的时候才生效。这也是为啥HashMap 扩容是2倍。当然这至少其中一个原因。