一.概述
Deque是Queue的子接口,我們知道Queue是一種隊列形式,而Deque則是雙向隊列,它支持從兩個端點方向檢索和插入元素,因此Deque既可以支持LIFO形式也可以支持LIFO形式.Deque接口是一種比Stack和Vector更為豐富的抽象數據形式,因為它同時實現了以上兩者.
二.主要方法
| 修飾符和返回值 | 方法名 | 描述 |
| 添加功能 | ||
| void | push(E) | 向隊列頭部插入一個元素,失敗時拋出異常 |
| void | addFirst(E) | 向隊列頭部插入一個元素,失敗時拋出異常 |
| void | addLast(E) | 向隊列尾部插入一個元素,失敗時拋出異常 |
| boolean | offerFirst(E) | 向隊列頭部加入一個元素,失敗時返回false |
| boolean | offerLast(E) | 向隊列尾部加入一個元素,失敗時返回false |
| 獲取功能 | ||
| E | getFirst() | 獲取隊列頭部元素,隊列為空時拋出異常 |
| E | getLast() | 獲取隊列尾部元素,隊列為空時拋出異常 |
| E | peekFirst() | 獲取隊列頭部元素,隊列為空時返回null |
| E | peekLast() | 獲取隊列尾部元素,隊列為空時返回null |
| 刪除功能 | ||
| boolean | removeFirstOccurrence(Object) | 刪除第一次出現的指定元素,不存在時返回false |
| boolean | removeLastOccurrence(Object) | 刪除最后一次出現的指定元素,不存在時返回false |
| 彈出功能 | ||
| E | pop() | 彈出隊列頭部元素,隊列為空時拋出異常 |
| E | removeFirst() | 彈出隊列頭部元素,隊列為空時拋出異常 |
| E | removeLast() | 彈出隊列尾部元素,隊列為空時拋出異常 |
| E | pollFirst() | 彈出隊列頭部元素,隊列為空時返回null |
| E | pollLast() | 彈出隊列尾部元素,隊列為空時返回null |
| 迭代器 | ||
| Iterator<E> | descendingIterator() | 返回隊列反向迭代器 |
可以看出Deque在Queue的方法上新添了對隊列頭尾元素的操作,add,remove,get形式的方法會在有界隊列滿員和空隊列時拋出異常,offer,poll,peek形式的方法則會返回false或null.
此外方法表中需要注意push = addFirst,pop = removeFirst,只是使用了不同的方法名體現隊列表示棧結構時的特點.
三.實現
同Queue一樣Deque的實現也可以划分成通用實現和並發實現.
通用實現主要有兩個實現類ArrayDeque和LinkedList.
ArrayDeque是個可變數組,它是在Java 6之后新添加的,而LinkedList是一種鏈表結構的list.LinkedList要比ArrayDeque更加靈活,因為它也實現了List接口的所有操作,並且可以插入null元素,這在ArrayDeque中是不允許的.
從效率來看,ArrayDeque要比LinkedList在兩端增刪元素上更為高效,因為沒有在節點創建刪除上的開銷.最適合使用LinkedList的情況是迭代隊列時刪除當前迭代的元素.此外LinkedList可能是在遍歷元素時最差的數據結構,並且也LinkedList占用更多的內存,因為LinkedList是通過鏈表連接其整個隊列,它的元素在內存中是隨機分布的,需要通過每個節點包含的前后節點的內存地址去訪問前后元素.
總體ArrayDeque要比LinkedList更優越,在大隊列的測試上有3倍與LinkedList的性能,最好的是給ArrayDeque一個較大的初始化大小,以避免底層數組擴容時數據拷貝的開銷.
LinkedBlockingDeque是Deque的並發實現,在隊列為空的時候,它的takeFirst,takeLast會阻塞等待隊列處於可用狀態
