概述
HashMap是基於Map接口的實現。這個實現提供了所有可選的映射操作,並且允許null值和null鍵。(除了不同步和允許空值以外,HashMap和Hashtable幾乎等價)。這個類不保證映射之間的順序;尤其是,它不保證隨着時間的推移映射順序不變(翻譯自Java API文檔)。
哈希表是一個“鏈表散列”的結構,是由數組和鏈表結合而成。
HashMap的基層是一個數組結構,而數組中的每一項又可以拓展成爲一個鏈表。具體的實現形式Entry就是數組中的元素,它是由key和value組成的基本單元,其本身持有Entry的引用來構成鏈表形式。
基本方法實現
此處源碼版本爲JDK1.7。
put方法
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
其實現的過程如下:
首先檢測key值,並由此得出它在數組中的index值,判斷是否已有key存在,若已在則覆蓋;若不存在則將新元素加到鏈表後,加元素操作具體由addEntry方法實現。
在addEntry方法中包含有擴容判斷和createEntry方法,createEntry方法將新創建的 Entry 放入 bucketIndex 索引處,並讓這個新的 Entry 指向原來的 Entry。
get方法
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
get方法中用getEntry來判斷key值在原數組中是否已存在並做取值操作。
總體來說,HashMap的底層是用Entry數組來實現的,通過key的哈希函數來尋找指定的key-value對位置並進行操作。
HashMap的refresh操作
當HashMap中的元素個數超過數組大小乘以負載因子時,就需要對HashMap進行擴容,類似的操作在List中也有。
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, initHashSeedAsNeeded(newCapacity));
table = newTable;
threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
}
新建Entry數組後將原數組中的元素轉移到新數組中,即重新計算它們在新數組中的位置。默認的負載因子是0.75,擴容規模爲原來的2倍。
以上爲對HashMap實現的基本理解,更詳細的內容參考http://zhangshixi.iteye.com/blog/672697