HashMap主要是由數(shù)組和鏈表組成枉疼,它不是線程安全的。
核心點就是put插入數(shù)據(jù)的過程该押,get查詢數(shù)據(jù)以及擴容的方式疗杉。JDK1.7和1.8的主要區(qū)別在于頭插和尾插方式的修改,頭插容易導(dǎo)致HashMap鏈表死循環(huán)蚕礼,并且1.8后加入紅黑樹對性能有提升烟具。
put插入數(shù)據(jù)流程
往map插入元素的時候,首先通過key 進行hash算法奠蹬,然后與數(shù)組長度-1進行與運算((n - 1) & hash)朝聋,都是2的次冪所以等同于取模,但位運算的效率更高囤躁。找到數(shù)組中的位置之后冀痕,如果數(shù)組中沒有元素直接則直接存入,反之則判斷key是否相同狸演,key相同就覆蓋言蛇,否則就會插入鏈表的尾部,如果鏈表的長度超過8宵距,則會轉(zhuǎn)換成紅黑樹腊尚,最后判斷數(shù)組長度是否超過默認長度*負載因子也就是12,超過則進行擴容满哪。
put方法流程
get查詢數(shù)據(jù)
查詢數(shù)據(jù)相對于來說就比較簡單了婿斥,首先計算出hash值,然后去數(shù)組查詢哨鸭,是紅黑樹則去紅黑樹查民宿,鏈表就遍歷鏈表查詢就可以了。
resize擴容過程
擴容的過程就是對key重新計算hash像鸡,然后把數(shù)據(jù)拷貝到新的數(shù)組活鹰。