Java為數(shù)據(jù)結(jié)構(gòu)中的映射定義了一個接口java.util.Map,此接口主要有四個常用的實現(xiàn)類,分別是HashMap、Hashtable、LinkedHashMap和TreeMap。
Hashmap
它根據(jù)鍵的hashCode值存儲數(shù)據(jù),訪問速度快,但遍歷順序卻是不確定的。
HashMap最多只允許一條記錄的鍵為null(多條會被覆蓋),允許多條記錄的值為null。
HashMap非線程安全,即任一時刻可以有多個線程同時寫HashMap,可能會導(dǎo)致數(shù)據(jù)的不一致。
如果需要滿足線程安全,可以用ConcurrentHashMap。
實現(xiàn)原理:HashMap在Map.Entry靜態(tài)內(nèi)部類實現(xiàn)中存儲key-value對。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。
當(dāng)我們通過傳遞key-value對調(diào)用put方法的時候,HashMap使用Key hashCode()和哈希算法來找出存儲key-value對的索引。Entry存儲在LinkedList中,所以如果存在entry,它使用equals()方法來檢查傳遞的key是否已經(jīng)存在,如果存在,它會覆蓋value,如果不存在,它會創(chuàng)建一個新的entry然后保存。
當(dāng)我們通過傳遞key調(diào)用get方法時,它再次使用hashCode()來找到數(shù)組中的索引,然后使用equals()方法找出正確的Entry,然后返回它的值。
LinkedHashMap
linkedHashMap 是hashmap的子類,保存了插入順序,其他和hashmap 保持一致的特性
TreeMap
TreeMap實現(xiàn)SortedMap接口,能夠把它保存的記錄根據(jù)鍵排序,默認是按鍵值的升序排序,也可以指定排序的比較器。
Hashtable
Hashtable繼承自Dictionary類,鍵不能null 線程安全。并發(fā)性不如ConcurrentHashMap,不再建議使用。
簡單來說,Hashtable通過給方法加synchronized實現(xiàn)線程安全。而ConcurrentHashMap是由Segment數(shù)組結(jié)構(gòu)和HashEntry數(shù)組結(jié)構(gòu)組成。Segment是一種可重入鎖ReentrantLock,在ConcurrentHashMap里扮演鎖的角色,HashEntry則用于存儲鍵值對數(shù)據(jù)。一個ConcurrentHashMap里包含一個Segment數(shù)組,Segment的結(jié)構(gòu)和HashMap類似,是一種數(shù)組和鏈表結(jié)構(gòu), 一個Segment里包含一個HashEntry數(shù)組,每個HashEntry是一個鏈表結(jié)構(gòu)的元素, 每個Segment守護一個HashEntry數(shù)組里的元素,當(dāng)對HashEntry數(shù)組的數(shù)據(jù)進行修改時,必須首先獲得它對應(yīng)的Segment鎖。
分段鎖可理解為,把整個Map分成了N個Segment,put和get的時候,根據(jù)key.hashCode()找到該使用哪個Segment,這個Segment做到了類似于Hashtable的線程安全,分段鎖就是說用到哪部分就鎖哪部分。ConcurrentHashMap鍵值不能為null。
轉(zhuǎn)載來源:https://blog.csdn.net/login_sonata/article/details/76598675