java集合框架總結(List、Set、Map)

集合框架

從上面的集合框架圖可以看到,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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章