HashMap原始碼解析JDK1 8 二 之put

2021-09-29 18:53:10 字數 2687 閱讀 7316

之前已經有兩篇文章介紹了hashmap的基本屬性及它的4個構造方法,這篇主要介紹下它的put方法,即資料的儲存;

首先,我們看下我們平常呼叫的put方法:

public v put

(k key, v value)

這個方法就是我們用的最多的put方法,實際入參就只有2個,乙個是我們稱為key,乙個我們稱為value,也就是鍵值對;這個方法實際很簡單,就是呼叫了裡面的另乙個put方法,這個方法有5個引數:

第乙個引數就是key的hash值,第二個和第三個就是我們傳入的鍵值對,第四個引數叫onlyifabsent,什麼意思呢?就是說只有當值不存在的時候才放入我們傳入的值,也就是說如果這個引數為true,不會改變已經存在的值;第五個引數叫evict,如果為true,則代表列表是在建立模式;接下來看下原始碼的方法**:

final v putval

(int hash, k key, v value,

boolean onlyifabsent,

boolean evict)

if(e.hash == hash &&

((k = e.key)

== key ||

(key != null && key.

equals

(k))))

break

; p = e;}}

if(e != null)

}++modcount;if(

++size > threshold)

//如果長度大於閥值,調製陣列容量;

resize()

;afternodeinsertion

(evict)

;return null;

}

首先這個方法是final修飾的,也就代表這個方法不能被重寫;

第一行**是定義了4個臨時變數, tab、 p、 n、 i;可以看到,tab與p都是node型別,那我們看下node的定義:

static

class

node

implements

map.entry

public

final k getkey()

public

final v getvalue()

public

final string tostring()

public

final

inthashcode()

public

final v setvalue

(v newvalue)

public

final

boolean

equals

(object o)

return

false;}

}

這個node類是乙個靜態的內部類,實現了map.entry介面;這個類實際上是乙個單向鍊錶結構;裡面的方法相對簡單,就不具體講了;

回到putval方法,第二行**的if條件,首先是把table賦值給tab,並且判斷是否為空或者把tab的長度賦值給n並判斷是否為0;換句話說,如果table沒有初始化,則呼叫resize()方法進行初始化,來看下resize()方法:

final node

resize()

//否則,新容量為老的容量2倍(左移1位),並且判斷是否小於最大容量,並且舊的容量大於等於預設初始容量,都滿足才進行真正的擴容

elseif(

(newcap = oldcap <<1)

< maximum_capacity &&

oldcap >= default_initial_capacity)

newthr = oldthr <<1;

// double threshold

}//如果不滿足上述條件,舊的閥值大於0,則新容量設定為舊的閥值

else

if(oldthr >0)

// initial capacity was placed in threshold

newcap = oldthr;

else

//如果新的閥值為0,設定新的閥值;即計算的閥值如果都小於最大容量,則設定該值為新的閥值,否則設定為integer.max_value

if(newthr ==0)

threshold = newthr;

@suppresswarnings()

//建立新的node陣列,長度為newcap

node

newtab =

(node

)new

node

[newcap]

;//賦值給table,此時table為空的node陣列,長度為新的容量

table = newtab;

//當舊的tab不為空時,需要對陣列重新調整

if(oldtab != null)

else

}while

((e = next)

!= null);if

(lotail != null)

if(hitail != null)}}

}}return newtab;

}

這也是個final型別的方法,大致的理解在**的注釋中;

**的大值分析就暫時到這裡;

JDK1 7HashMap原始碼解析

hashmap已經看了很多篇文章了,今天還是自己解析一遍吧。我先大致介紹下hashmap的內部結構再跟著原始碼解讀一番 眾所周知hashmap的內部就是乙個雜湊表 什麼是雜湊表?如果我們利用陣列可隨機訪問的特性,將要存入的鍵通過一種雜湊演算法轉換成乙個數字,並把這個數字轉換成陣列的下標,然後將鍵和他...

JDK1 8 HashMap原始碼解析

普通常量 儲存node鍊錶的陣列 transient node table 由node節點構成的set集合 transient set entryset hashmap儲存元素的數量 transient int size 記錄hashmap結構性變化的次數 value覆蓋不算 和fail fast機...

JDK 1 8 HashMap原始碼解析

put方法分析 public v put k key,v value hash方法解析 減少hash衝突 static final int hash object key putval方法具體實現 final v putval int hash,k key,v value,boolean onlyi...