引言
最近在讀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...