HashMap 系列文章
- HashMap 的自定義常量分析
- HashMap 的構造函數分析
- HashMap 的 hash 算法和尋址地址的優(yōu)化
前言
上一節(jié)我們分析了 HashMap 的自定義常量的含義掠哥,這一節(jié)帶大家分析一下 HashMap 的構造函數。
HashMap()
HashMap 無參構造函數秃诵,默認 table 初始化是 16龙致,默認的加載因子是 0.75,這個在上一講也講過了顷链,DEFAULT_INITIAL_CAPACITY 是 16,DEFAULT_LOAD_FACTOR 是 0.75屈梁。
HashMap(int initialCapacity)
HashMap(int initialCapacity)嗤练,可以對容量進行設置,加載因子是 DEFAULT_LOAD_FACTOR 在讶,調用的是下面的有參構造函數煞抬。
HashMap(int initialCapacity, float loadFactor)
HashMap(int initialCapacity, float loadFactor),可以指定容量和加載因子构哺。容量不可以小于 0 革答,也不可以無限大。加載因子也不能是 0 曙强,也不能比 0 小残拐。并且不能是 NaN (詳見)。
然后給 loadFactor 進行賦值碟嘴,并且給對閾值 threshold 進行設置溪食。我們可以看一下 tabSizeFor 方法。
對于給定的容量進行計算娜扇,返回 2 的 n 次方错沃。那這塊的計算規(guī)則,我給你們講解一下雀瓢。
首先我們看一下運算符的優(yōu)先級 (詳見)
我們知道先進行位移預算枢析,再進行與運算,然后再給 n 進行賦值刃麸。
這塊的意思是什么醒叁,就是以你的最高位為基準,然后讓后面的位置都是1嫌蚤。
那我舉個例子辐益,你就明白了,
比如 cap 是 17脱吱,那么 n 就是 17-1 = 16
16 對應的二進制是 10000智政。
那咱們一步一步的算:
首先
n |= n>>>1
n >>> 1,標識 n 右移 1 位箱蝠,那么 n = 01000
10000 | 01000 = 11000
n = 11000
第二步
n >>> 2, 標識 n 右移 2 位续捂,那么 n = 00110
11000|00110 = 11110
n = 11110
第三步
得到 n = 11111
最終就得到 n = 11111 也就是換算成十進制也就是 31垦垂,那返回結果就是 31+1 = 32
所以不管你輸入的是多少,比如十進制 100 換算成二進制就是 1100100 那么得到的結果就是 1111111 就是 127牙瓢,那返回結果就是 128劫拗。
而為什么偏要是 2 的 n 次方呢?這里提前透露一下矾克,當進行 put 的時候页慷,會計算 hash 值,然后進行 hash 值得優(yōu)化胁附,并且把優(yōu)化后的 hash 值和 size-1 進行一個與(&)運算酒繁。這個會在后續(xù)進行更詳細的講解。
HashMap(Map<? extends K, ? extends V> m)
HashMap(Map map) 創(chuàng)建一個新的 HashMap 控妻,加載因子是 DEFAULT_LOAD_FACTOR 州袒。然后通過 putMapEnries 將 map 的值存儲到新的 HashMap 中。
putMapEntries 方法主要分為三步
- 如果 HashMap 沒有創(chuàng)建弓候,給閾值設值郎哭。
- 如果 HashMap 不為 null,根據閾值判斷是否需要擴容菇存。
-
通過 entrySet() 獲取 map 的所有鍵值夸研,通過循環(huán),用 getKey() 和 getValue() 獲取鍵值依鸥,然后 put 到新的 HashMap 中陈惰。
總結
HashMap 有四個構造函數,分別是:
- HashMap()
- HashMap(int initialCapacity)
- HashMap(int initialCapacity, float loadFactor)
- HashMap(Map<? extends K, ? extends V> m)
通過構造函數可以設置容量和加載因子毕籽,容量必須大于 0 抬闯,最大不能超過 MAXIMUM_CAPACITY,而且通過 tabSizeFor(int cap) 方法返回 2 的 n 次方关筒,并且賦值給 threshold溶握。threshold 是 HashMap 的閾值,在 resize() 方法初始化 table 的時候蒸播,threshold 是初始化 table 的容量大小睡榆。這個 resize() 方法在后面會詳細講解。所以為了減少擴容和 hash 沖突袍榆,我們可以在創(chuàng)建 HashMap 的時候提前控制容量和加載因子的大小胀屿,來提升系統的性能。