hashmap是基於陣列和鍊錶來儲存鍵值對物件的,我們簡單看下get和put方法的原始碼。
1、我們呼叫put方法來儲存鍵值對時,它先呼叫hash方法來計算hashcode,然後用hashcode和entry陣列的大小來做按位與操作,求出所在的entry陣列的下標位置。通過key與下標所在的entry鍊錶進行判斷是否已經存在此key,如果存在就重新設定value為新的值,不存在則加入到entry鍊錶中。加入鍊錶是加入到原頭結點之前,如下原始碼。如果key為null時,特殊處理,將null放到了第乙個entry鍊錶中。
public v put(k key, v value)
if (key == null)
return putfornullkey(value);
//計算hashcode
int hash = hash(key);
//計算所在entry陣列(table)的下標
int i = indexfor(hash, table.length);
//判斷是否存在此key,存在就替換value,並返回新值。
for (entrye = table[i]; e != null; e = e.next)
}//modcount值增加,此值是iterator迭代時用來判斷是否有其他執行緒對資料做過修改,如果做過修改則丟擲concurrentmodificationexception
modcount++;
//走到這,說明此key不存在於hashmap中,增加節點。
addentry(hash, key, value, i);
return null;
}//增加節點方法,首先判斷是否需要擴容,如果需要擴容則重新計算hash
void addentry(int hash, k key, v value, int bucketindex)
createentry(hash, key, value, bucketindex);
}//建立節點方法,將entry鍊錶的頭結點取出,將新entry指向原來的頭結點,table對應的下標指向新的頭結點。
void createentry(int hash, k key, v value, int bucketindex)
//entry的構造方法。
entry(int h, k k, v v, entryn)
//如果是null值,直接放到第乙個entry鍊錶中。
private v putfornullkey(v value)
}modcount++;
addentry(0, null, value, 0);
return null;
}
2、當呼叫get方法獲取key時,對於null值特殊處理,直接從table[0]中獲取。否則,計算key的hash值,找到key所在的entry鍊錶,遍歷此鍊錶找出對應的key值。
public v get(object key)
//計算hash,遍歷對應的鍊錶。
final entrygetentry(object key)
int hash = (key == null) ? 0 : hash(key);
for (entrye = table[indexfor(hash, table.length)];
e != null;
e = e.next)
return null;
}//null值從第乙個entry鍊錶中獲取。
private v getfornullkey()
for (entrye = table[0]; e != null; e = e.next)
return null;
}
HashMap原始碼 get方法
環境 jdk1.8 get方法原始碼如下 public v get object key hash方法原始碼如下 static final int hash object key getnode方法原始碼如下 傳入引數 1.根據key雜湊計算得到的雜湊值 2.key值 final nodegetno...
JDK原始碼之HashMap
部分重要屬性 存放key,value的陣列 transient node table 存放entry的set transient set entryset hashmap的大小 預設16 transient int size 修改次數 transient int modcount 擴擴容閾值capa...
原始碼分析之HashMap
首先hashmap繼承了abstractmap,並且實現了map cloneable和serializable三個介面。cloneable和serializable是比較常規的兩個介面,在這裡並不作為重點。重點將會放在abstractmap和map兩個規範上。其中abstractmap是乙個抽象類,...