HashMap原始碼分析

2021-07-06 10:10:42 字數 2453 閱讀 4531

public

hashmap(int initialcapacity, float loadfactor)

(2)接下來是重要的put方法,put方法用於將鍵值對儲存到map中,讓我們來具體分析一下。

public v put(k key, v value) 

if (key == null)

//若key為null,則將value放到table第0個位置

//若有值,將覆蓋

return putfornullkey(value);

//對key進行一次hash,目的在於使得獲得的hash值中的0、1均勻

int hash = hash(key);

//獲得該key在table中的位置

int i = indexfor(hash, table.length);

//獲得i這個位置的entry物件,判斷是否為空,若不為空則遍歷i這個位置的鍊錶,如果有相同的key,將舊的value覆蓋

for (entrye = table[i]; e != null; e = e.next)

}modcount++;

//往乙個位置i新增entry

addentry(hash, key, value, i);

return

null;

}

然後看看addentry的實現。

void addentry(int hash, k key, v value, int bucketindex) 

createentry(hash, key, value, bucketindex);

}//擴容

void resize(int newcapacity)

entry newtable = new entry[newcapacity];

//將舊表內容賦值到新錶中

//transfer的過程其實也挺簡單,只是根據inithashseedasneeded(newcapacity)的結果決定是否需要rehash

//如果需要rehash就重新hash一次,找到新位置,否則就根據原來的hash值找到在新錶中的位置

transfer(newtable, inithashseedasneeded(newcapacity));

table = newtable;

threshold = (int)math.min(newcapacity * loadfactor, maximum_capacity + 1);

}

至此put方法已經分析完畢,總結一下:(1)如果key為null,將entry放到第乙個位置,如果存在則覆蓋。(2)對key進行hash,找到位置,如果存在相同的key則覆蓋。(3)判斷一下是否需要擴容,如需要則將size變成2倍,根據hashseed計算是否需要rehash,將已經存在的entry賦值到新table。(4)將新的entry放到合適的位置。

接下來分析一下get方法。

public v get(object key) 

final entrygetentry(object key)

//計算hash值

int hash = (key == null) ? 0 : hash(key);

for (entrye = table[indexfor(hash, table.length)];

e != null;

e = e.next)

return

null;

}

get方法總結如下:(1)判斷key是否為null,如果是去第0個位置取值。(2)計算hash值,找到在table中的位置,遍歷那個位置上的entry鍊錶,找到key相等的並返回value。

hashmap有兩種典型的遍歷方式。

map

<

string, string

>

map=

new hashmap<

string, string

>();

for (map

.entry<

string, string

> entry : map

.entryset())

set<

string

>

set=

map.keyset();

iterator<

string

> it =

set.iterator();

while (it.hasnext())

這兩種遍歷方式呼叫的keyset和entryset方法,本質上沒有太大的區別,都呼叫了ha****erator的nextentry方法,keyset呼叫的是nextentry.getkey方法。但是從最終的遍歷來看,entryset的遍歷效率應該是比keyset稍高的,推薦用這個方式。

HashMap 原始碼分析

1 getentry object key 方法 final entrygetentry object key return null 根據key的hash值計算出索引,得到table中的位置,然後遍歷table處的鍊錶 for entrye table indexfor hash,table.le...

HashMap原始碼分析

public v put k key,v value if key null return putfornullkey value int hash hash key int i indexfor hash,table.length for entrye table i e null e e.nex...

HashMap原始碼分析

size記錄了所有鍵值對的數目,包括陣列 內部實現 中的和陣列某些位置附屬鍊錶 hash值相同,不允許覆蓋已存在的鍵值對,所以要以鍊錶形式附加 中的鍵值對。hashmap的內部實現是陣列 鍊錶,通過鍵的hash值來定位鍵值對在陣列中的位置,是一種離散結構,所以陣列的某些索引上沒有儲存元素。1.預設引...