Map用於存儲「key-value」元素對,它將一個key映射到一個並且只能是惟一的一個value。 Map可使用多種實現方式,HashMap的實現採用的是hash表;而TreeMap採用的是紅黑樹。java
** java.util包提供了大量集合類。其中最經常使用的集合類有List、Set、Map等。 **數組
首先,來看下java.util包中Map相關的集合類。Map往下提供了兩個接口:ConcurrentMap和SortedMap。ConcurrentMap是java5中新增的線程安全的Map接口;而SortedMap則是支持排序的Map接口。經常使用的就屬Hashtable、HashMap和TreeMap了。另外,java5新增了HashMap的併發版本ConcurrentHashMap。安全
** Hashtable 和 HashMap **多線程
Hashtable和HashMap都實現了Map接口,可是Hashtable的實現是基於Dictionary抽象類。併發
在HashMap中,null能夠做爲鍵,這樣的鍵只有一個;能夠有一個或多個鍵所對應的值爲null。 當get()方法返回null值時,便可以表示HashMap中沒有該鍵,也能夠表示該鍵所對應的值爲null。所以,在HashMap中不能由get()方法來判斷HashMap中是否存在某個鍵, 而應該用containsKey()方法來判斷。而在Hashtable中,不管是key仍是value都不能爲null 。性能
這兩個類最大的不一樣在於Hashtable是線程安全的,它的方法是同步了的,能夠直接用在多線程環境中,Hashtable中採用的鎖機制是一次鎖住整個hash表,從而同一時刻只能由一個線程對其進行操做;而HashMap則不是線程安全的,在多線程環境中,須要手動實現同步機制。線程
** 更好的選擇:ConcurrentHashMap **指針
java5中新增了ConcurrentMap接口和它的一個實現類ConcurrentHashMap,ConcurrentHashMap提供了Hashtable不一樣的鎖機制。 ConcurrentHashMap 在默認併發級別會建立包含 16 個 Segment 對象的數組。每一個 Segment 的成員對象 table 包含若干個散列表的桶。每一個桶是由 HashEntry 連接起來的一個鏈表。若是鍵能均勻散列,每一個 Segment 大約守護整個散列表中桶總數的 1/16。對象
在 ConcurrentHashMap 中,線程對映射表作讀操做時,通常狀況下不須要加鎖就能夠完成,對容器作結構性修改的操做才須要加鎖。相比較於 HashTable 和由同步包裝器包裝的 HashMap每次只能有一個線程執行讀或寫操做,ConcurrentHashMap 在併發訪問性能上有了質的提升。在理想狀態下,ConcurrentHashMap 能夠支持 16 個線程執行併發寫操做(若是併發級別設置爲 16),及任意數量線程的讀操做。排序
在迭代方面,ConcurrentHashMap使用了一種不一樣的迭代方式。在這種迭代方式中,當iterator被建立後集合再發生改變就再也不是拋出ConcurrentModificationException, 取而代之的是在改變時new新的數據從而不影響原有的數據 ,iterator完成後再將頭指針替換爲新的數據 ,這樣iterator線程可使用原來老的數據,而寫線程也能夠併發的完成改變。