全是个人理解产物,仅供参考
我们常说,HashMap中的算法是通过%进行取模,但是实际上源码是这样的
i = (n - 1) & hash
那到底是不是弄错了?
首先从其他地方得知,桶数必须是2的幂次方,也就是1,2,4,8……
假设桶数 | 1 | 2 | 4 | 8 |
---|---|---|---|---|
对应n-1的值 | 0 | 1 | 3 | 7 |
用二进制表示(int是四字节32位,我们只取后8位) | 0000 0000 | 0000 0001 | 0000 0011 | 0000 0111 |
然后位运算符&其实有一个用法,就是保留需要的位,比如
假设此时有个有符号数数是127,即0111 1111
想保留的位数(左起) | &的值 |
---|---|
1、3 | 0111 1111 & 0000 0101 —————— 0000 0101 |
1、3、5、6 | 0111 1111 & 0011 0101 —————— 0011 0101 |
那么可以得出,(n - 1) & hash实际上就是看想保留几位,2的0次幂保留0位,2的1次幂就是保留1位,2的m次幂就是保留m位,所以放在哪个桶,看上去和前几位似乎没有任何关系?为什么没有关系?
假设hash值为15,即0000 1111,桶为8,即(n-1)为7,0000 0111,那么取模后,得到的是0000 0111,被忽略的是0000 1000,会发现这不就是8吗,可以被桶数8整除,当然可以忽略,同理0000 0111之上的任何一位,第四位是8,第五位是16,全部都是可以被8整除的,所以前面所有的位都可以忽略
综上,(n-1)&hash还是取模的思想,不过前期是桶需要为2的幂次方。之所以这么干,我想是因为位运算速度比%快很多把
以上为个人见解