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

2022-10-06 02:54:09 字數 1252 閱讀 6059

引言

最近在讀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    &nbsikropryp;       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()的一行**,用於判斷在擴容後原陣列中的元素是ikropry否需要移動。舉個例子:

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的屬性

public class hashmap extends abstractmap implements map,cloneable,serializable容載因子 容載因子越大,table陣列中儲存的資料越密集,碰撞的可能性就越大。容載因子越小,儲存越稀疏,碰撞的可能性就越小,不過浪費儲存空間。轉...

HashMap原始碼解讀

一 建立乙個hashmap都做了哪些工作?mapmap new hashmap hahmap無參構造方法 public hashmap 可以看到設定了載入因子 預設0.75 閾值 預設容量16 預設載入因子0.75 12 table是hashmap內部資料儲存結構entry陣列。當hashmap的s...

HashMap原始碼分析

public hashmap int initialcapacity,float loadfactor 2 接下來是重要的put方法,put方法用於將鍵值對儲存到map中,讓我們來具體分析一下。public v put k key,v value if key null 若key為null,則將va...