HashMap源碼中的位運算符&詳解
引言
最近在讀HashMap源碼的時候,發(fā)現(xiàn)在很多運算符替代常規(guī)運算符的現(xiàn)象。比如說用hash & (table.length-1) 來替代取模運算hash&(table.length);用if((e.hash & oldCap) == 0)判斷擴容后元素的位置等等。
1.取模運算符%底層原理
總所周知,位運算&直接對二進制進行運算;而對于取模運算符%:a % b 相當于 a - a / b * b,底層實際上是除法器,究其根源也是由底層的減法和加法共同完成。所以其運行效率要遠遠小于位運算符&。
2.位運算符&如何實現(xiàn)取模功能
我們先來看兩個例子
5 & 7 9 & 7
0101----5 1001----9
& &
0111----7 0111----7
= =
0101----5 0001----1
確實,hash & (table.length-1) 來實現(xiàn)了運算hash&(table.length)從二進制的角度來說,5%8實際上是將二進制5(0101)向右移動3位,而與7(0111)進行與運算實際上就是將位數(shù)向右移動三位。不過要注意的是,只有當length的長度為2^n時,結(jié)論才成立。
3.位運算符&在if((e.hash & oldCap) == 0)判斷擴容后元素的位置
這是出自于JDK1.8中擴容函數(shù)resize()的一行代碼,用于判斷在擴容后原數(shù)組中的元素是否需要移動。舉個例子:
0001 1010----26 0000 1010----10
& &
0001 0000----16 0001 0000----16
= =
0001 0000----非0 0000 0000-----0
利用hash值和oldCap進行與運算,很明顯當結(jié)果大于0代表hash值大于oldCap時,下標位置變?yōu)榕f數(shù)組的下標j + oldCap;若結(jié)果等于0代表小于oldCap,則下標位置不變。相比于JDK1.7重新計算每個元素的哈希值,通過高位運算(e.hash & oldCap)無疑效率更高。
到此這篇關(guān)于HashMap源碼中的位運算符&詳解的文章就介紹到這了,更多相關(guān)HashMap源碼中的位運算符&內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Swing JPasswordField密碼框的實現(xiàn)示例
這篇文章主要介紹了Java Swing JPasswordField密碼框的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12基于Springboot+Netty實現(xiàn)rpc的方法 附demo
這篇文章主要介紹了基于Springboot+Netty實現(xiàn)rpc功能,在父項目中引入相關(guān)依賴結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02