HashMap之put 操作
阿新 • • 發佈:2018-08-27
val key值 沒有 存在 cap resize map 擴容 tor key值為空的情況:
進行putForNull操作:
1.判斷key值為null的Entry是否需存在,如果存在則將老值替換成新值(oldValue=newValue,返回老值),如果不存在的話,就addEntry(0,null,value,0)
2.addEntry(int hash, K key, V value, int bucketIndex)
在添加新的Entry的時候,Entry.key的hash計算出的位置如果有Entry元素的時候,將元素加入到該鏈表的頭部,先進入的放到鏈表的尾部
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
//加入該項到鏈表頭部
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
} 0.75;如果到達最大容量,threshold=MAX_VALUE;如果沒有超過則將長度擴大為之前的兩倍,創建新的Entry數組,將新的數據transfer到新的Entry數組中,再將新的Entry數組賦值給老的Entry數組,此時將threshold=擴容後的Entry數組的長度* 加載因子
進行putForNull操作:
1.判斷key值為null的Entry是否需存在,如果存在則將老值替換成新值(oldValue=newValue,返回老值),如果不存在的話,就addEntry(0,null,value,0)
2.addEntry(int hash, K key, V value, int bucketIndex)
在添加新的Entry的時候,Entry.key的hash計算出的位置如果有Entry元素的時候,將元素加入到該鏈表的頭部,先進入的放到鏈表的尾部
void addEntry(int hash, K key, V value, int bucketIndex) {
//加入該項到鏈表頭部
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
3.擴容首先要判斷老的Map的長度是否大於等於最大的長度(1<<30,左移30位)
如果大於等於 ,threshold(判斷是否擴容的條件即table.size>threshold),擴容位之前的兩倍(threshold=DEFAULT_INITAL_CAPACITYDEFAULT_LOAD_FACTOR )=>16
void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = oldTable.length; if (oldCapacity == MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; return; } Entry[] newTable = new Entry[newCapacity]; ** transfer(newTable);** table = newTable; threshold = (int)(newCapacity * loadFactor); } 4.transfer 將原數組中的數據傳輸到新的數組中 遍歷 Entry 數組,遍歷每個列下面的鏈表 void transfer(Entry[] newTable) { Entry[] src = table; int newCapacity = newTable.length; for (int j = 0; j < src.length; j++) { Entry<K,V> e = src[j]; if (e != null) { src[j] = null; do { Entry<K,V> next = e.next; int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } while (e != null); } }
HashMap之put 操作