1. 程式人生 > 程式設計 >HashMap原始碼中的位運算子&詳解

HashMap原始碼中的位運算子&詳解

引言

最近在讀HashMap原始碼的時候,發現在很多運算子替代常規運算子的現象。比如說用hash & (table.length-1) 來替代取模運算hash&(table.length);用if((e.hash & oldCap) == 0)判斷擴容後元素的位置等等。

1.取模運算子%底層原理

​總所周知,位運算&直接對二進位制進行運算;而對於取模運算子%:a % b 相當於 a - a / b * b,底層實際上是除法器,究其根源也是由底層的減法和加法共同完成。所以其執行效率要遠遠小於位運算子&。

HashMap原始碼中的位運算子&詳解

2.位運算子&如何實現取模功能

​我們先來看兩個例子

5 & 7 9 & 7
0101----5 1001----9
& &
0111----7 0111----7
= =
0101----50001----1

​確實,hash & (table.length-1) 來實現了運算hash&(table.length)從二進位制的角度來說,5%8實際上是將二進位制5(0101)向右移動3位,而與7(0111)進行與運算實際上就是將位數向右移動三位。不過要注意的是,只有當length的長度為2^n時,結論才成立。

3.位運算子&在if((e.hash & oldCap) == 0)判斷擴容後元素的位置

​這是出自於JDK1.8中擴容函式resize()的一行程式碼,用於判斷在擴容後原陣列中的元素是否需要移動。舉個例子:

0001 1010----26 0000 1010----10
& &
0001 0000----16 0001 0000----16
= =
0001 0000----非0 0000 0000-----0

利用hash值和oldCap進行與運算,很明顯當結果大於0代表hash值大於oldCap時,下標位置變為舊陣列的下標j + oldCap;若結果等於0代表小於oldCap,則下標位置不變。相比於JDK1.7重新計算每個元素的雜湊值,通過高位運算(e.hash & oldCap)無疑效率更高。

到此這篇關於HashMap原始碼中的位運算子&詳解的文章就介紹到這了,更多相關HashMap原始碼中的位運算子&內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!