深入瞭解雙端佇列Deque
本文出自部落格Vander丶CSDN部落格,如需轉載請標明出處,尊重原創謝謝
Deque的類圖
由上圖可知Deque在Java中以介面的形式存在,同時Deque還繼承Queue(佇列)的介面。
Queue佇列
佇列是一種特殊的線性容器,它是一種先進先出(FIFO)的資料結構。
它只允許在容器的頭部進行刪除操作,而在表的後端進行插入操作。進行插入操作的端成為隊尾,進行刪除操作的端稱為隊頭。
當佇列中沒有元素時,被稱為空佇列。
同理當插入元素已經充滿佇列,被稱為滿佇列.
Queue佇列的原始碼解析
Queue的插入操作
/**
* 相同點:
* 插入為null的元素,會報空指標
* 插入與執行泛型不符的型別會報型別轉換異常
* 插入某些不允許插入的元素,會阻止其插入,IDE會提示非法引數
*
* 不同點:
* 在滿佇列狀態下:
* 使用add()方法會報IllegalStateException異常,提示佇列已滿.
* 使用offer()方法在此情況下不會報異常而返回false.
*/
boolean add(E e);
boolean offer(E e);
上述兩種方法都是插入操作,當插入元素成功時,會返回true.
不同點:
注意 : 佇列中不允許插入為null的元素,否則會報空指標.
在進行插入操作時,一般情況推薦使用offer()來插入元素.
Queue的取出操作
/**
* 相同點:
* 都是Queue的取出操作,返回值為佇列容器頭部元素.
*
* 不同點:
* 當處於空佇列狀態時,remove()方法會丟擲佇列為空,沒有匹配元素的的異常
* 而poll()方法則會返回null值,不會報異常.
*/
E remove();
E poll();
在進行刪除操作時,一般情況推薦使用poll()來取出元素
Queue的檢索操作
/**
* 相同點:
* 都是Queue的檢索操作,返回值為佇列容器頭部元素,但是不會刪除元素.
*
* 不同點:
* 當處於空佇列狀態時,element()方法會丟擲佇列為空,沒有匹配元素的的異常
* 而peek()方法則會返回null值,不會報異常.
*/
E element();
E peek();
在進行檢索操作時,一般情況推薦使用peek()來取出元素
下圖將佇列(Queue)的操作進行了總結 :
Deque(雙端佇列)的介紹
Deque的含義是“double ended queue”,即雙端佇列.
Deque是一種具有佇列和棧的性質的資料結構.雙端佇列中的元素可以從兩端彈出,其限定插入和刪除操作在表的兩端進行.
通過開始的類圖可以發現,Deque繼承了Queue(佇列)的介面,它的直接實現有ArrayDeque、LinkedList等。
Deque的容量有兩種模式,一種是固定長度,另一種是容量無限。
同Queue一樣,Deque也定義了兩套操作訪問元素的方法,比如在頭部和尾部進行插入、刪除、檢索元素、同樣的,一種是在滿佇列或者空佇列的操作元素時,會報異常,而另一種則會return null或者return false。
這裡引用了博主“瘋子123”的博文,對於Deque介紹的示意圖
由於Deque介面繼承Queue介面,當Deque當做佇列使用時(FIFO),只需要在頭部刪除,尾部新增即可。
除此之外,Deque也可以當做棧(後進先出)使用,這時入棧,出棧的元素都在雙端佇列的頭部進行。
看圖在結合Queue的分析,大家就會明白Deque方法的含義。
Deque的實現類
Deque的使用場景
在一般情況,不涉及到併發的情況下,有兩個實現類,可根據其自身的特性進行選擇,分別是:
LinkedList 大小可變的連結串列雙端佇列,允許元素為 null
ArrayDeque 大下可變的陣列雙端佇列,不允許 null
注意:LinkedList 和ArrayDeque是執行緒不安全的容器。
在併發場景下,推薦使用LinkedBlockingDeque:
LinkedBlockingDeque(阻塞的雙向佇列)
因為LinkedBlockingDeque在佇列為空的情況下,獲取操作將會阻塞,直到有元素新增。
關於ArrayDeque、LinkedList
因為網上對於ArrayDeque已經有詳細的介紹,這裡就不打算在進行重複的去翻譯API,直接附上鍊接。
內含LinkedList和ArrayDeque。
參考文章:
1.Java 集合深入理解(10):Deque 雙端佇列
http://www.cnblogs.com/hehehaha/p/6147206.html
2.同步容器、併發容器、阻塞佇列、雙端佇列與工作密取
http://www.tuicool.com/articles/jE3IV3