一、建立乙個hashmap都做了哪些工作?
mapmap = new hashmap();
hahmap無參構造方法
public hashmap()
可以看到設定了載入因子(預設0.75)、閾值(預設容量16*預設載入因子0.75=12)、table是hashmap內部資料儲存結構entry陣列。當hashmap的size大於等於閾值時,hashmap會擴容到原來的容量的2倍。而如果 new hashmap(1),它的容量是不是1呢?可以看到最終呼叫的構造方法:
public hashmap(int initialcapacity) :
最終呼叫的是下面的
public hashmap(int initialcapacity, float loadfactor)
可以看到hashmap的size總是2的倍數,即new hashmap(1)的最終容量是2.
entry是什麼呢?entry就是map中存放的key-value對,並且儲存了下乙個節點的引用next和key的hash值,也就實現了鍊錶的功能。
entry結構體:
hashmap儲存結構圖:
二、put(key,value)的實現
public v put(k key, v value)
}modcount++;
addentry(hash, key, value, i);
return null;
}
hashmap允許存null key值,它會把key為null放到table[0]的位置,即第乙個bucket(table陣列中的元素稱為bucket桶)。
新增乙個新元素時,先根據key值計算出hash碼,根據hash碼計算出所在bucket的位置i。遍歷table[i]下掛的entry,如果key值存在就覆蓋value,不存在就新增新的entry。
void addentry(int hash, k key, v value, int bucketindex)
擴容之後把原來的元素轉移過來,重新hash,重新分配bucket位置,同乙個bucket鏈結的entry會倒序鏈結起來。entry(int h, k k, v v, entryn)
addentry方法中判斷容量是否超過閾值,若超過會擴容到原來的2倍大小。
void resize(int newcapacity)
entry newtable = new entry[newcapacity];
transfer(newtable);
table = newtable;
threshold = (int)(newcapacity * loadfactor);
}
void transfer(entry newtable) while (e != null);}}
}
三、get(key)的實現
get就比較簡單,按照hash碼找到對應的bucket,遍歷掛載的entry,若key值相同就返回對應的value,若找不到就返回null。
public v get(object key)
return null;
}
四、hash衝突處理方法
1、開放位址法
2、鏈位址法
hashmap處理hash衝突採用的鏈位址法
HashMap原始碼解讀
今日閒來無事,擷取一段hashmap的 分析一下 int hash hash key 根據key 的hashcode 計算hash值 int i indexfor hash,table.length 根據hash值 計算出再陣列中的位置 for entrye table i e null e e.n...
HashMap原始碼解讀
hashmap原始碼分析 me 對集合檢視的迭代,hashmap的桶數加實際大小與時間成正比,也就是說,不可以把桶樹設定的太多或負載因子太小。o 對集合檢視的迭代需要與hashmap 例項的 容量 桶數 加上其大小 鍵值對映的數量 成比例的時間。因此,如果迭代效能很重要,則不要將初始容量設定得太高 ...
HashMap原始碼解讀
public v put k key,v value static final int hash object key final v putval int hash,k key,v value,boolean onlyifabsent,boolean evict 如果在遍歷鍊錶中途,發現可以值相等...