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.預設引...