有一段時間沒有更新了。接着上節繼續吧。java
Queue除了前面介紹的實現外,還有一種雙向的Queue實現Deque。這種隊列容許在隊列頭和尾部進行入隊出隊操做,所以在功能上比Queue顯然要更復雜。下圖描述的是Deque的完總體系圖。須要說明的是LinkedList也已經加入了Deque的一部分(LinkedList是從jdk1.2 開始就存在數據結構)。數組
Deque在Queue的基礎上增長了更多的操做方法。安全
從上圖能夠看到,Deque不只具備FIFO的Queue實現,也有FILO的實現,也就是不只能夠實現隊列,也能夠實現一個堆棧。數據結構
同時在Deque的體系結構圖中能夠看到,實現一個Deque可使用數組(ArrayDeque),同時也可使用鏈表(LinkedList),還能夠同實現一個支持阻塞的線程安全版本隊列LinkedBlockingDeque。性能
對於數組實現的Deque來講,數據結構上比較簡單,只須要一個存儲數據的數組以及頭尾兩個索引便可。因爲數組是固定長度的,因此很容易就獲得數組的頭和尾,那麼對於數組的操做只須要移動頭和尾的索引便可。.net
特別說明的是ArrayDeque並非一個固定大小的隊列,每次隊列滿了之後就將隊列容量擴大一倍(doubleCapacity()),所以加入一個元素老是能成功,並且也不會拋出一個異常。也就是說ArrayDeque是一個沒有容量限制的隊列。線程
一樣繼續性能的考慮,使用System.arraycopy複製一個數組比循環設置要高效得多。對象
對於LinkedList自己而言,數據結構就更簡單了,除了一個size用來記錄大小外,只有head一個元素Entry。對比Map和Queue的其它數據結構能夠看到這裏的Entry有兩個引用,是雙向的隊列。blog
在示意圖中,LinkedList老是有一個「傀儡」節點,用來描述隊列「頭部」,可是並不表示頭部元素,它是一個執行null的空節點。索引
隊列一開始只有head一個空元素,而後從尾部加入E1(add/addLast),head和E1之間創建雙向連接。而後繼續從尾部加入E2,E2就在head和E1之間創建雙向連接。最後從隊列的頭部加入E3(push/addFirst),因而E3就在E1和head之間連接雙向連接。
雙向鏈表的數據結構比較簡單,操做起來也比較容易,從事從「傀儡」節點開始,「傀儡」節點的下一個元素就是隊列的頭部,前一個元素是隊列的尾部,換句話說,「傀儡」節點在頭部和尾部之間創建了一個通道,是整個隊列造成一個循環,這樣就能夠從任意一個節點的任意一個方向能遍歷完整的隊列。
一樣LinkedList也是一個沒有容量限制的隊列,所以入隊列(無論是從頭部仍是尾部)總能成功。
上面描述的ArrayDeque和LinkedList是兩種不一樣方式的實現,一般在遍歷和節省內存上ArrayDeque更高效(索引更快,另外不須要Entry對象),可是在隊列擴容下LinkedList更靈活,由於不須要複製原始的隊列,某些狀況下可能更高效。
一樣須要注意的上述兩個實現都不是線程安全的,所以只適合在單線程環境下使用,下面章節要介紹的LinkedBlockingDeque就是線程安全的可阻塞的Deque。事實上也應該是功能最強大的Queue實現,固然了實現起來也許會複雜一點。