圖學java基礎篇之集合

(本文部分圖片引用自其餘博客,最後有連接,侵刪。因爲筆記使用markdown記錄,格式可能不是太好看,見諒)html

集合結構


紅字爲java.util包下的,綠字爲concurrent包下擴展的與併發相關的類java

List

ArrayList

功能:有序非線程安全列表
要點:git

  • 底層存儲用Object數組
  • 元素可爲null
  • 自動擴容至1.5倍
  • 適合隨機訪問,不適合大量或頻繁增刪
LinkedList

功能:有序非線程安全列表
要點:github

  • 基於雙向鏈表實現
  • 元素可爲null
  • 同時實現了雙端隊列Deque,支持隊列、堆棧操做
  • 適合增刪,順序訪問,不適合隨機訪問
Vector

功能:有序線程安全列表
要點:算法

  • 功能和ArrayList同樣,只有線程安全區別,效率較ArrayList低
  • 實際上算是老版本的List,除了線程安全的狀況下不用
Stack

功能:基於Vector實現的堆棧
要點:數組

  • 線程安全
  • 後進先出(LIFO)1
CopyOnWriteArrayList

功能:快照版本的ArrayList,修改操做經過複製一份數組操做
要點:安全

  • 線程安全
  • 任何修改都會在拷貝的新副本上進行
  • 修改操做經過ReentrantLock同步
  • 迭代器只能訪問,不能修改,且不會由於遍歷過程當中修改而拋異常
實現線程安全List的方法
  • 使用synchronized:對List操做是進行同步,須要本身控制
  • 使用Vector:效率低,已經較少使用了
  • 使用CopyOnWriteArrayList,前邊已經介紹了,這個只能在量小讀多寫少的場景下用,且性能不好,通常不要用
  • 使用Collections.synchronizedList():工具類提供的一個比較簡便的方法,能夠直接建立一個線程安全的list,建議使用。其原理是對ArrayList進行包裝,經過一個對象鎖來控制併發,須要注意的是要弄清楚對象鎖鎖的是哪一個對象。

Map

HashMap

功能:
要點:key-value的map,存儲位置根據key的hash值肯定markdown

  • 非線程安全
  • 底層使用Entry<K, V>數組table
  • 衝突使用鏈存儲
  • table長度爲2^n,這樣結合hash算法有利於均勻分佈
  • 當發生衝突時,新元素會插入到鏈首
  • 每次table容量變化時,須要從新rehash
  • 鍵值都可爲null
HashTable

功能:key-value的map,存儲位置根據key的hash值肯定,與Hash的算法不一樣之處是,其位置直接經過hash(key)%table.length計算(HashMap使用h&(length – 1)計算,效率更高,才外還有一些細節不一樣,可自行參看源碼)
要點:數據結構

  • 線程安全
  • 繼承自Dictionary
  • 底層使用Entry<K, V>數組table
  • 衝突使用鏈存儲
  • table長度爲2^n,這樣結合hash算法有利於均勻分佈
  • 當發生衝突時,新元素會插入到鏈首
  • 每次table容量變化時,須要從新rehash
  • 鍵值不能爲空
TreeMap

功能:基於紅黑樹實現的有序集合
要點:架構

  • 非線程安全
  • 底層爲一個棵紅黑樹
  • 繼承NavigableMap,主要實現了SortMap,所以是有序的
  • 增刪改查均可參考紅黑樹操做
ConcurrentHashMap

功能:線程安全的HashMap,屬於java.util.concurrent下的拓展類
要點:

  • 線程安全
  • 底層實現是一個Segment<K, V>數組,Segment內部經過一個HashEntry<K, V>數組存儲元素數據,同時Segment繼承了ReentrantLock,直接經過自己的鎖對改段數據操做同步
  • 從底層結構能夠發現,其修改時不會對整個集合加鎖,而是對段加鎖,所以容許同時修改多個段,效率更高
  • 繼承NavigableMap,主要實現了SortMap,所以是有序的
  • Segment的劃分是經過key的hashCode計算
ConcurrentSkipListMap

功能:線程安全的有序Map,是經過一個叫作跳錶的數據結構實現
要點:

  • 線程安全
  • 底層實現是一個多層鏈表,每層元素都有序,每低一層都包含上一層的元素,最底層包含全部元素。這樣設計的巧妙之處是從上層逐層查找時,可以快速定位元素區間。思想上有點像折半查找,不過是把每次折半的中間值分層存了起來。同時鏈表結構是修改操做一樣高效
  • key是有序的
  • 空間換時間,效率很高,可是空間佔用也很厲害
Map的用法
  • 非線程安全情景基本上都用HashMap
  • 有序用TreeMap
  • 線程安全優先ConcurrentHashMap
  • ConcurrentHashMap和ConcurrentSkipListMap的優劣主要在於併發量,併發量不高時前者效率高,併發量很大時能夠考慮後者

Set

HashSet

功能: 就是一個value均爲同一個PRESENT對象的HashMap
要點:

  • 非線程安全
  • 底層爲一個HashMap,其全部元素value值是一個Object類型的靜態常量
  • 其餘參考HashMap
TreeSet

功能: 同TreeMap
要點:

  • 非線程安全
  • 底層爲一個TreeMap,其全部元素value值是一個Object類型的靜態常量
  • 其餘參考TreeMap
ConcurrentSkipListSet

功能: 同ConcurrentSkipListMap

CopyOnWriteArraySet

功能: 同ConcurrentSkipListMap
要點:

  • 須要注意的是底層實現是經過CopyOnWriteArrayList,而非HashMap
  • 使用場景與CopyOnWriteArrayList同樣

Queue

Queue實現了隊列操做,是基本集合的一個擴充,特色是提供了隊列操做offer、poll和peek,主要分爲兩類,一類只支持單端操做,常見的如PriorityQueue,另外一類爲雙端隊列,可實現堆棧操做,均實現Deque。需注意的是隊列也提供了add和remove,但應避免使用。

PriorityQueue

功能:如其名,優先級隊列,可根據Comparator實現優先級排列
要點:

  • 非線程安全
  • 底層爲一個Object數組
  • 不提供Comparator時按照元素天然順序
ArrayDeque

功能:如其名,優先級隊列,可根據Comparator實現優先級排列
要點:

  • 非線程安全
  • 底層爲一個E[]數組,同時提供head和tail記錄存儲數據的首位位置
  • 因爲使用數組不是鏈表,速度比LinkedList更快
LinkedBlockingDeque

功能:阻塞隊列,支持支持FIFO和FILO
要點:

  • 線程安全
  • 底層爲一個鏈表,經過一個ReentrantLock鎖控制併發
  • 可指定容量,實現阻塞,隊滿時插入阻塞,隊空時讀取阻塞,不指定則取最大整數
  • 注意take在空時不阻塞直接返回失敗,而poll則會阻塞
  • 可指定元素超時時間
LinkedBlockingQueue

功能:阻塞隊列,和LinkedBlockingDeque基本同樣,不過支持隊列操做

PriorityBlockingQueue

功能:優先級阻塞隊列,直接看名字,不解釋了

SynchronousQueue

功能:阻塞隊列,特殊之處在於其不存儲元素,一個元素入隊以後必須出隊,不然阻塞,能夠理解爲1個元素的阻塞隊列

LinkedTransferQueue

功能:LinkedBlockingQueue和SynchronousQueue的結合體,特色是若是一個元素入隊過程當中發現又出隊請求,則直接返回,不會再插入鏈表中
要點:

  • 注意其併發並不是經過ReentrantLock,而是經過LockSupport工具類實現
DelayQueue

功能:延遲隊列,只有達到指定時間的元素才能出隊
要點:

  • 底層實現是一個PriorityQueue,經過ReentrantLock控制併發
  • 能夠理解爲一個以入隊時間-延遲時間爲優先級的隊列

一些使用上的淺見

  • 從上邊的總結能夠看出來java對於集合的實現很是完善,幾乎全部場景都有對應的類。所以咱們應該避免重複造輪子,在合適的場景下使用合適的集合不只省力,並且更可靠
  • 能簡則不繁,其實多數狀況下咱們使用基本的幾個類就夠了,複雜的實現通常用於底層框架_(如JDK以及一些經常使用框架中就用到了很多併發的實現,但其場景都十分鮮明)_。若是平時寫也想上層邏輯時使用了負責的集合類,每每咱們須要認真考慮下真的有沒有必要,或者這部分是否是能夠抽象爲一個通用的組件,這算是個頗有用的代碼架構技巧吧。
  • 不管怎麼用,理解至上。幾個基本類之因此用的順手是由於咱們熟悉其特性,而對於複雜的集合類必定要理解其特性,不然很容易踩坑。集合部分算是JDK中最容易理解的代碼了,花一下子時間而保證優質代碼仍是很值的。

備註

一些參考博客 (都是很優秀的博客,若我的看源碼吃力,能夠參考着這些博客來看)
http://cmsblogs.com/?cat=5
http://my.oschina.net/lifany/blog/191294
http://blog.csdn.net/guangcigeyun/article/details/8278349
http://www.cnblogs.com/skywang12345/p/3503480.html
http://www.infoq.com/cn/articles/java-blocking-queue/
http://my.oschina.net/readjava/blog/282882
http://hyxw5890.iteye.com/blog/1578597

以上xmind圖源文件以及該系列相關文件都將同步至github,敬請關注

相關文章
相關標籤/搜索