HashMap 的實例有兩個參數(shù)影響其性能:初始容量 和加載因子。容量 是哈希表中桶的數(shù)量,初始容量只是哈希表在創(chuàng)建時的容量。加載因子 是哈希表在其容量自動增加之前可以達(dá)到多滿的一種尺度。當(dāng)哈希表中的條目數(shù)超出了加載因子與當(dāng)前容量的乘積時,則要對該哈希表進(jìn)行 rehash 操作(即重建內(nèi)部數(shù)據(jù)結(jié)構(gòu)),從而哈希表將具有大約兩倍的桶數(shù)。
通常,默認(rèn)加載因子 (.75) 在時間和空間成本上尋求一種折衷。加載因子過高雖然減少了空間開銷,但同時也增加了查詢成本(在大多數(shù) HashMap 類的操作中,包括 get 和 put 操作,都反映了這一點)。在設(shè)置初始容量時應(yīng)該考慮到映射中所需的條目數(shù)及其加載因子,以便最大限度地減少 rehash 操作次數(shù)。如果初始容量大于最大條目數(shù)除以加載因子,則不會發(fā)生 rehash 操作。
很多人都有這個疑問,為什么hashmap的數(shù)組初始化大小都是2的次方大小時,hashmap的效率最高,我以2的4次方舉例,來解釋一下為什么數(shù)組大小為2的冪時hashmap訪問的性能最高。本文主要描述了HashMap的結(jié)構(gòu),和hashmap中hash函數(shù)的實現(xiàn),以及該實現(xiàn)的特性,同時描述了hashmap中resize帶來性能消耗的根本原因,以及將普通的域模型對象作為key的基本要求。尤其是hash函數(shù)的實現(xiàn),可以說是整個HashMap的精髓所在,只有真正理解了這個hash函數(shù),才可以說對HashMap有了一定的理解。
① hashmap是用鏈地址法進(jìn)行處理,多個key 對應(yīng)于表中的一個索引位置的時候進(jìn)行鏈地址處理,hashmap其實就是一個數(shù)組+鏈表的形式。
② 當(dāng)有多個key的值相同時,hashmap中只保存具有相同key的一個節(jié)點,也就是說相同key的節(jié)點會進(jìn)行覆蓋。
③在hashmap中查找一個值,需要兩次定位,先找到元素在數(shù)組的位置的鏈表上,然后在鏈表上查找,在HashMap中的第一次定位是由hash值確定的,第二次定位由key和hash值確定。
④節(jié)點在找到所在的鏈后,插入鏈中是采用的是頭插法,也就是新節(jié)點都插在鏈表的頭部。
⑤在hashmap中上圖左邊綠色的數(shù)組中也存放元素,新節(jié)點都是放在左邊的table中的,這個在上圖中為了形象的表現(xiàn)鏈表形式而沒有使用。