1. 程式人生 > >HashMap,Hashtable和ConcurrentHashMap

HashMap,Hashtable和ConcurrentHashMap

面試的時候經常會問到的問題?這三個之間有什麼區別.

 Hashtable是遺留類,現在基本上不使用,其內部都是通過關鍵字synchronized來實現執行緒安全,所以Hashtable是HashMap的執行緒安全版本,可以這樣說.因為加了鎖,使得效率變低.


ConcurrentHashMap

ConcurrentHashMap是JDK1.5引入的Concurrent包中類,這個包的主程式碼由多執行緒大師Doug Lea編寫,ConcurrentHashMap現在已經基本取代了Hashtable,因為它在保證執行緒安全的前提大,大大提高併發環境下的處理能力,ConcurrentHashMap採用分段鎖的概念,在ConcurrentHashMap的內部有一個類叫Segment,它類似於HashTable,繼承於ReentrantLock以達到執行緒安全的目的.




 ConcurrentHashMap不同於Hashtable在於分段鎖消除不同分段鎖之間的競爭,只有鎖內部存在競爭.而Hashtable是在整個Map上新增同步.ConcurrentHashMap預設Segment的個數是16,當物件要存入集合內時,首先通過物件的鍵計算HashCode值來找到對應的Segment,然後將物件新增到對應的Segment之中,相對於Hashtable的效率提高了16倍.

HashMap

 HashMap是我們使用得最多的集合,就通過一個程式碼例項來說吧!使用物件的形式做為HashMap的鍵.



結果:


結論:

HashMap可以存放鍵值對,如果要以物件(自己建立的類等)作為鍵,實際上是以物件的雜湊值(以hashCode方法計算得到)

作為鍵。hashCode計算的hash值預設是物件的地址值。這樣就會忽略物件的內容,不是以物件的內容來判斷。如果要以物件

的內容進行判斷,就要覆蓋掉物件原有的hashCode方法。另外HashMap是以equals方法判斷當前的鍵是否與表中存在的鍵

是否相同,所以覆蓋hashCode方法之後,還不能正常執行。還要覆蓋equals方法先判斷hash(hash函式)值是否相同,相

同了說明某個位置上有多個元素,再用equals(線性查詢)方法判斷。這裡上次面試回來仍然搞錯了,因為我記得HashMap

的鍵要實現Compareable介面,其實是我記錯了,JDK1.7HashMap的資料結構如下:


這也糾正了好久以來一個錯誤的認知,HashMap的鍵必須實現Compareable介面,因為它的鍵是一個Set集合,值是List集合,我一

定是記錯了,記成TreeMap和TreeSet,資料結構樹必須實現Compareable介面.

JDK1.8HashMap的資料結構如下:


 JDK1.8HashMap的底層實現可以參考:

 http://www.th7.cn/Program/java/201607/892575.shtml

 JDK1.8HashMap與Compareable介面的那點事可以參考:
 http://blog.csdn.net/zly9923218/article/details/51656920