HashMap
HashMap基于哈希表的 Map 接口的實(shí)現(xiàn)卑笨。允許使用 null 值和 null 鍵。不保證映射的順序翁涤,特別是它不保證該順序恒久不變盗迟。HashMap不是線程安全的,可以通過(guò)Collections類的靜態(tài)方法synchronizedMap獲得線程安全的HashMap灸撰。
HashMap的底層主要是基于數(shù)組和鏈表來(lái)實(shí)現(xiàn)的。HashMap中主要是通過(guò)key的hashCode來(lái)計(jì)算hash值的拼坎,只要hashCode相同浮毯,計(jì)算出來(lái)的hash值就一樣。如果存儲(chǔ)的對(duì)象對(duì)多了泰鸡,就有可能不同的對(duì)象所算出來(lái)的hash值是相同的债蓝,這就出現(xiàn)了所謂的hash沖突。解決hash沖突的方法有很多盛龄,HashMap底層是通過(guò)鏈表來(lái)解決hash沖突的饰迹。
HashMap其實(shí)就是一個(gè)Entry數(shù)組千扔,Entry對(duì)象中包含了鍵和值憎妙,其中next也是一個(gè)Entry對(duì)象,它就是用來(lái)處理hash沖突的曲楚,形成一個(gè)鏈表厘唾。
/** Entry是單向鏈表。
* 它是 “HashMap鏈?zhǔn)酱鎯?chǔ)法”對(duì)應(yīng)的鏈表龙誊。
*它實(shí)現(xiàn)了Map.Entry 接口抚垃,即實(shí)現(xiàn)getKey(), getValue(), setValue(V value), equals(Object o), hashCode()這些函數(shù)
**/
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
// 指向下一個(gè)節(jié)點(diǎn)
Entry<K,V> next;
final int hash;
// 構(gòu)造函數(shù)。
// 輸入?yún)?shù)包括"哈希值(h)", "鍵(k)", "值(v)", "下一節(jié)點(diǎn)(n)"
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
//......
}
HashMap類的關(guān)鍵屬性
1 transient Entry[] table;//存儲(chǔ)元素的實(shí)體數(shù)組 默認(rèn)初始長(zhǎng)度為 16
2
3 transient int size;//存放元素的個(gè)數(shù)
4
5 int threshold; //臨界值 當(dāng)實(shí)際大小超過(guò)臨界值時(shí)趟大,會(huì)進(jìn)行擴(kuò)容threshold = 加載因子*容量
6
7 final float loadFactor; //加載因子 默認(rèn)0.75
8
9 transient int modCount;//被修改的次數(shù)
注意:
1鹤树、HashMap中通過(guò)hash&(length-1)的方法來(lái)代替取模(Hashtable中)來(lái)實(shí)現(xiàn)哈希值對(duì)應(yīng)數(shù)組下標(biāo)的映射。
2逊朽、哈希表的容量一定要是2的整數(shù)次冪罕伯,保證散列的均勻。
3叽讳、當(dāng)哈希表的size>threshold時(shí),則調(diào)用Resize方法追他,此方法新建一個(gè)2*size的數(shù)組,并將舊數(shù)組中的數(shù)據(jù)復(fù)制到新數(shù)組中岛蚤,所以效率很低邑狸。