https://blog.csdn.net/doujinlong1/article/details/81196048
這裡,因為hashmap求陣列位置的時候都是直接hashcode&陣列大小,以前我只是想到一個數&一個數肯定會小,可以使得index在size之內取值。沒有考慮到hash碰撞的問題,後來看到一篇部落格後才理解。
首先取模操作時可以保證均分的,但是取模操作效能比較差,所以hashMap使用了近乎取模的&,並且是與上一個size-1的數,達成了變相取模的操作。
但是這時候,size是不是2的 n次方倍就至關重要了。
舉例如下,如果陣列大小是15(非2次方冪)和16(2次方冪)的區別。
1110(15-1)&hashcode
1111(16-1)&hashcode
假設hashcode從 1 到30,我們來看看結果:
1110 | 1111 |
1(0001)&1110 = 0 | 1(0001)&1111 = 1 |
2(0010)%1110 = 2 | 2(0010)%1111 = 2 |
3(0011)%1110= 2 | 3(0011)%1111= 3 |
4(0100)&1110 = 4 | 4(0100)&1111 = 4 |
5(0101)&1110 = 4 | 5(0101)&1111 = 5 |
。。。。。。
可以明顯的看出來,在15的時候,這種&操作代替取模操作的特點不存在,也就是說,不能保證hashcode對應的key放到陣列均分,size = 15的時候,明顯所有尾數帶1的陣列位置上都不會有值。而後者 16 就可以保證均分,避免了摸操作,又均勻分配。這就是為什麼hashMap的 size 一定是2的 n次方倍