引言
最近在讀HashMap原始碼的時候,發現在很多運算子替代常規運算子的現象,比如說用hash & (table.length-1) 來替代取模運算hash&(table.length);用if((e.hash & oldCap) == 0)判斷擴容后元素的位置等等,
1.取模運算子%底層原理
? 總所周知,位運算&直接對二進制進行運算;而對于取模運算子%:a % b 相當于 a - a / b * b,底層實際上是除法器,究其根源也是由底層的減法和加法共同完成,所以其運行效率要遠遠小于位運算子&,

2.位運算子&如何實作取模功能
? 我們先來看兩個例子
5 & 7 9 & 7
0101----5 1001----9
& &
0111----7 0111----7
= =
0101----5 0001----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)無疑效率更高,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/138759.html
標籤:Java
