從上面的集合框架圖可以看到,Java集合框架主要包括兩種類型的容器,一種是集合(Collection),存儲一個元素集合,另一種是圖(Map),存儲鍵/值對映射。Collection接口又有3種子類型,List、Set和Queue。**Set的集合裏不允許對象有重複的值,List允許有重複,Map不允許key重複。**常用的集合框架有ArrayList、LinkedList、Vector、HashSet、HashMap、Hashtable。
#List
-
ArrayList
-
底層是動態數組。
-
默認無參構造函數會初始化大小爲10,向集合中添加元素至集合滿的時候,會生成一個大小爲原來1.5倍的新集合,然後將集合中元素拷貝到新集合。
-
線程不安全。
-
Vector
-
底層是動態數組。
-
默認無參構造函數會初始化大小爲10,向集合中添加元素至集合滿的時候,會默認生成一個大小爲原來2倍的新集合(vector支持自定義增加係數),然後將集合中元素拷貝到新集合。
-
線程安全。
-
LinkedList
-
底層是雙向鏈表。
-
不需要考慮大小。
-
線程不安全。
使用:若需要對集合頻繁的查找,則使用ArrayList或Vector,若需要考慮線程安全,則選擇Vector;若需要頻繁的插入或刪除,則使用LinkedList。
#Set
-
HashSet
-
底層是HashMap。(區別是沒有key-value對)
-
默認無參構造函數會初始化大小爲16,向集合中添加元素至集合大小的0.75倍時,會生成一個大小爲原來2倍的新集合,然後重新計算元素的地址,將集合中元素插入到新集合。
-
線程不安全。
#Map
-
HashMap
-
底層是數組+鏈表+紅黑樹。JDK8中,鏈表長度不小於8時,將鏈表轉化爲紅黑樹。
-
默認無參構造函數會初始化大小爲16,向集合中添加元素至集合大小的0.75倍時,會生成一個大小爲原來2倍的新集合,然後重新計算元素的地址,將集合中元素插入到新集合,屆時效率很低。
-
線程不安全。(例如:put的時候導致的數據覆蓋、集合擴展時(resize方法)會出現死循環)
-
Hashtable
-
底層是數組+鏈表。(拉鍊法)
-
默認無參構造函數會初始化大小爲11,向集合中添加元素至集合大小的0.75時,會生成一個大小爲原來(2倍+1)的新集合,然後重新計算元素的地址,將集合中元素插入到新集合,屆時效率很低。
-
線程安全。
-
key和value都不允許爲null(HashSet允許一個null,HashMap允許一個key爲null)。
-
LinkedHashMap
-
底層是HashMap+雙向循環鏈表。
-
線程不安全。
-
ConcurrentHashMap
通過分析Hashtable可知,synchronized是針對整張Hash表的,即每次鎖住整張表讓線程獨佔,ConcurrentHashMap允許多個修改操作併發進行,其關鍵在於使用了鎖分離技術。它使用了多個鎖來控制對hash表的不同部分進行的修改。
併發度可以理解爲程序運行時能夠同時更新ConccurentHashMap且不產生鎖競爭的最大線程數,實際上就是ConcurrentHashMap中的分段鎖個數,即Segment[]的數組長度。ConcurrentHashMap默認的併發度爲16,但用戶也可以在構造函數中設置併發度。當用戶設置併發度時,ConcurrentHashMap 會使用大於等於該值的最小2冪指數作爲實際併發度(假如用戶設置併發度爲17,實際併發度則爲32)。運行時通過將key的高n位(n = 32 – segmentShift)和併發度減1(segmentMask)做位與運算定位到所在的Segment。segmentShift與segmentMask都是在構造過程中根據concurrency level被相應的計算出來。
如果併發度設置的過小,會帶來嚴重的鎖競爭問題;如果併發度設置的過大,原本位於同一個Segment內的訪問會擴散到不同的Segment中,CPU cache命中率會下降,從而引起程序性能下降。
ConcurrentHashMap和Hashtable主要區別就是圍繞着鎖的粒度以及如何鎖,可以簡單理解成把一個大的HashTable分解成多個,形成了鎖分離。
ConcurrentHashMap的弱一致性主要是爲了提升效率,是一致性與效率之間的一種權衡。要成爲強一致性,就得到處使用鎖,甚至是全局鎖,這就與Hashtable和同步的HashMap一樣了。
JDK7與JDK8中HashMap的實現
https://my.oschina.net/hosee/blog/618953
ConcurrentHashMap總結
https://my.oschina.net/hosee/blog/675884
ConcurrentHashMap能完全替代HashTable嗎?
https://my.oschina.net/hosee/blog/675423
ConcurrentHashMap原理分析
https://my.oschina.net/hosee/blog/639352
LinkedHashmap源碼剖析
http://blog.csdn.net/ns_code/article/details/37867985