HashMap的源碼、實現原理以及JDK8中做了哪些優化
JDK8之前採用數組(位桶)+鏈表的方式實現,通過鏈表處理衝突;
JDK8之後採用數組+鏈表+紅黑樹的方式實現;使用鏈表存儲的優點是可以降低內存的使用率,而紅黑樹的優點是查詢效率更好;JDK8在二者之間做了一定的平衡。
HashMap的擴容機制
擴容一般發生在插入元素的時候,當數組的使用率超過負載因子的時候(默認值是0.75)便會選擇擴容,擴容為原有容量的2倍;
為什麼總是2倍擴容?
在插入元素的時候,首先根據key的hashcode找到對應的桶位,java並沒有利用取模的方式確定桶位,而是與數據length-1進行與運算確定桶位,如果length是2的倍數,那麼length-1的二進制全部是1,就會更具備隨機性;否則對於0的位永遠不會被隨機到,那麼對應的桶也就不會被利用。
HashMap & HashTable & CurrentHashMap的區別
hashmap的實現不是線程安全的,不適合應用於多線程環境;
hashtable是線程安全的,通過在方法上加上 synchronized 實現,效率相對比較低;
CurrentHashMap也是線程安全的,通過分段鎖實現,可與允許多線程同時讀寫數據;
另外Map還有一種線程安全的實現方式 通過Collections類提供的synchronizedMap方法:Map的包裝,與Hashtable的實現類似;
併發環境下使用HashMap會導致什麼問題
get元素的時候可能出現死循環,原因是:在多線程rehash的過程可能會形成循環鏈表,導致查找元素的時候一致無法遍歷完這個鏈表。
閱讀更多 IT技術百貨 的文章