兄弟姐妹
HashMap:快,遍歷順序不確定袁稽,非線程安全
Hashtable:遺留類勿璃,線程安全,只有一個線程能寫推汽,并發(fā)性能較差
LinkedHashMap:記錄插入順序
ConcurrentHashMap:線程安全补疑,分段鎖
HashMap是什么
從結(jié)構(gòu)實現(xiàn)來講,HashMap是數(shù)組+鏈表+紅黑樹(JDK1.8增加了紅黑樹部分)實現(xiàn)的歹撒,如下如所示莲组。
重要組成:
Node:實現(xiàn)了Map.Entry接口,本質(zhì)是就是一個映射(鍵值對)暖夭。
Node[] table:哈希桶數(shù)組
int threshold:所能容納的k-v對極限(table.length * load factor)
final float loadFactor:負(fù)載因子
int modCount:結(jié)構(gòu)變化次數(shù)(put新的算锹杈,但是覆蓋value不算)
int size:當(dāng)前map中的k-v數(shù)量
設(shè)計思路
本質(zhì):空間成本和時間成本之間權(quán)衡
其實就是在根據(jù)實際情況確定哈希桶數(shù)組的大小,并在此基礎(chǔ)上設(shè)計好的hash算法減少Hash碰撞迈着。
那么通過什么方式來控制map使得Hash碰撞的概率又小竭望,哈希桶數(shù)組(Node[] table)占用空間又少呢?答案就是好的Hash算法和擴容機制裕菠。
在HashMap中咬清,哈希桶數(shù)組table的長度length大小必須為2的n次方(一定是合數(shù)),這是一種非常規(guī)的設(shè)計奴潘,常規(guī)的設(shè)計是把桶的大小設(shè)計為素數(shù)旧烧。相對來說素數(shù)導(dǎo)致沖突的概率要小于合數(shù)。主要是為了在取模和擴容時做優(yōu)化画髓,同時為了減少沖突掘剪,HashMap定位哈希桶索引位置時,也加入了高位參與運算的過程奈虾。
原理實現(xiàn)
1.確定哈希桶數(shù)組索引位置
hash()夺谁、取模運算的巧妙(來計算該對象應(yīng)該保存在table數(shù)組的哪個索引處,當(dāng)length = 2^n時肉微,h&(length-1) = h%length匾鸥,&比%更高效)
2.分析HashMap的put方法
putVal()
3.擴容機制
遍歷舊的數(shù)組和所有node,重新計算hash浪册,再refresh扫腺。
區(qū)別1.7和1.8(引入紅黑樹)
小結(jié)
1.擴容是特別消耗性能的岗照,在能估算map大小的時候村象,可以初始化一個數(shù)值笆环。
2.HashMap是線程不安全的,會造成死循環(huán)
3.jdk1.8中的紅黑樹對HashMap的性能優(yōu)化
拓展
Hash哈希
- 可變數(shù)據(jù)類型的操作改變厚者,導(dǎo)致哈希值的改變
ConcurrentHashMap
- 分段鎖
- 對于size()的統(tǒng)計