之前已經有兩篇文章介紹了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...