HashMap 下标计算
从HashMap源码中,可以看到求容器下标值的方法,有两步,首先通过key值计算hash,然后用hash计算下标: 计算hash: return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); 计算下标,其下标值为:(n-1) & hash n = (tab = resize()).length; p = tab[i = (n - 1) & hash] 即,是通过key的hash值和容器的大小减1,两者进行与运算,获取容器数组下标。这里使用与运算,其实蕴含了一个隐藏条件,即数组的大小n,必须是2的n次方,否则,计算出来的下标值i是无法覆盖这个范围[0, n-1]的。 举个例子,假设两种情况,一种容器大小为10,不是2的幂,另外一种容器大小为16,刚好是2的4次方。 则,对于第一种,n-1= 9, 二进制表示为 1001,任何值与该值进行与运算,都无法改变中间的两个0,只能改变首尾的两个1,因此结果范围就缩小了一倍 而,对于第二种,n-1=15,二进制表示为 1111,该值与其他值与运算后,可以覆盖范围[0, 15],而这个范围刚好是数组的大小,因此只要hash值均匀分布,结果也是均匀的。 实际上,只要数组大小是2的幂,则 (n-1) & hash 的结果等效于: hash % (n-1)