概念
1序宦、hashmap 是對map接口的實現(xiàn)
2睁壁、hashmap底層是將key-value當(dāng)成一個整體進(jìn)行處理,這個整體就是一個Entry對象互捌。hashmap底層采用Entry[]數(shù)組來保存所有的key-value.
3潘明、存儲一個entry對象時,會利用hash算法根據(jù)key計算出hashcode值來決定其在數(shù)組中的位置秕噪。當(dāng)出現(xiàn)hashcode值相同時钳降,則會發(fā)生hash碰撞,接著會將值以鏈表的形式存儲在一起腌巾。
4遂填、當(dāng)獲取值時铲觉,根據(jù)key找到對應(yīng)entry數(shù)組的位置,然后遍歷鏈表吓坚,通過keys.equals()方法找到對象撵幽。
面試點
1、hashmap的初始容量 16 2的冪次方
2礁击、hashmap的負(fù)載因子(load) 默認(rèn)0.75
3盐杂、何時會發(fā)生容量擴容:
1)當(dāng)size/capacity大于默認(rèn)負(fù)載因子時。
2)size是所有key-value的總數(shù)
3)capacity是容量哆窿,capacity就是指HashMap中桶的數(shù)量
4链烈、擴容的大小:第一次會由16變成64挚躯,之后每次是原來的兩倍
5测垛、當(dāng)兩個對象的hashcode相同時會發(fā)生什么
·會發(fā)生hash碰撞,該對象會被存儲在同一個bucket下秧均,以鏈表的形式結(jié)合食侮,jdk1.8中當(dāng)鏈表長度超過8時,會生成紅黑樹的形式
6目胡、如何減少碰撞的發(fā)生
·使用string和integer這種包裝類作為key
·因為他們是final類型的锯七,不可變性
7、重新調(diào)整hashmap的大小存在什么問題
·1誉己、多線程情況下眉尸,出現(xiàn)條件競爭:會出現(xiàn)死循環(huán)的情況
2、建議不要使用hashmap進(jìn)行多線程操作
8巨双、多線程情況的意見
·1噪猾、使用concurrenthashmap類,線程安全并且效率和hashmap差不多筑累,細(xì)粒度操作(對bucket加鎖)
2袱蜡、使用Collections.synchronizedMap(new Hashmap())
3、hashtable
4慢宗、其中hashtable 和collections類的map 都是對整個map加鎖的坪蚁。
9、為什么hashmap不是線程安全的
·1镜沽、擴容時敏晤,由于調(diào)整大小過程中,存儲在linkedList中的元素次序會反過來缅茉,導(dǎo)致多線程操作嘴脾,出現(xiàn)環(huán)鏈的情況,進(jìn)而引發(fā)死鎖蔬墩。
2译打、兩個線程操作同一個hashmap時耗拓,如果一個線程更改了hashmap的結(jié)構(gòu)則另一個線程調(diào)用iterator迭代時,會出現(xiàn)concurrentmodificationException (方法檢測到對象的并發(fā)修改,引發(fā)異常)扶平,產(chǎn)生fail-fast事件