Java中的queue和deque對比詳解

隊列(queue)簡述

隊列(queue)是一種經常使用的數據結構,能夠將隊列看作是一種特殊的線性表,該結構遵循的先進先出原則。Java中,LinkedList實現了Queue接口,由於LinkedList進行插入、刪除操做效率較高。html

在處理元素前用於保存元素的 collection。除了基本的 Collection 操做外,隊列還提供其餘的插入、提取和檢查操做。每一個方法都存在兩種形式:一種拋出異常(操做失敗時),另外一種返回一個特殊值(null 或 false,具體取決於操做)。插入操做的後一種形式是用於專門爲有容量限制的 Queue 實現設計的;在大多數實現中,插入操做不會失敗。java

 

  拋出異常 返回特殊值
插入 add(e) offer(e)
移除 remove() poll()
檢查 element() peek()

隊列一般(但並不是必定)以 FIFO(先進先出)的方式排序各個元素。不過優先級隊列和 LIFO 隊列(或堆棧)例外,前者根據提供的比較器或元素的天然順序對元素進行排序,後者按 LIFO(後進先出)的方式對元素進行排序。不管使用哪一種排序方式,隊列的 都是調用 remove() 或 poll() 所移除的元素。在 FIFO 隊列中,全部的新元素都插入隊列的末尾。其餘種類的隊列可能使用不一樣的元素放置規則。每一個 Queue 實現必須指定其順序屬性。編程

Queue 接口並未定義阻塞隊列的方法,而這在併發編程中是很常見的。BlockingQueue 接口定義了那些等待元素出現或等待隊列中有可用空間的方法,這些方法擴展了此接口。api

Queue 實現一般不容許插入 null 元素,儘管某些實現(如 LinkedList)並不由止插入 null。即便在容許 null 的實現中,也不該該將 null 插入到 Queue 中,由於 null 也用做 poll 方法的一個特殊返回值,代表隊列不包含元素。數據結構

Queue 實現一般未定義 equals 和 hashCode 方法的基於元素的版本,而是從 Object 類繼承了基於身份的版本,由於對於具備相同元素但有不一樣排序屬性的隊列而言,基於元素的相等性並不是老是定義良好的。併發

 

Queue經常使用方法:

  1. boolean add(E e);將指定的元素插入此隊列(若是當即可行且不會違反容量限制),在成功時返回 true,若是當前沒有可用的空間,則拋出 IllegalStateException
  2. boolean offer(E e);將指定的元素插入此隊列(若是當即可行且不會違反容量限制),當使用有容量限制的隊列時,此方法一般要優於 add(E),後者可能沒法插入元素,而只是拋出一個異常。
  3. E remove();獲取並移除此隊列的頭。
  4. E poll();獲取並移除此隊列的頭,若是此隊列爲空,則返回 null
  5. E element();獲取,可是不移除此隊列的頭。
  6. E peek();獲取但不移除此隊列的頭;若是此隊列爲空,則返回 null

雙端隊列(Deque)簡述

雙向隊列(Deque),是Queue的一個子接口,雙向隊列是指該隊列兩端的元素既能入隊(offer)也能出隊(poll),若是將Deque限制爲只能從一端入隊和出隊,則可實現棧的數據結構。對於棧而言,有入棧(push)和出棧(pop),遵循先進後出原則。spa

一個線性 collection,支持在兩端插入和移除元素。名稱 deque 是「double ended queue(雙端隊列)」的縮寫,一般讀爲「deck」。大多數 Deque 實現對於它們可以包含的元素數沒有固定限制,但此接口既支持有容量限制的雙端隊列,也支持沒有固定大小限制的雙端隊列。.net

此接口定義在雙端隊列兩端訪問元素的方法。提供插入、移除和檢查元素的方法。每種方法都存在兩種形式:一種形式在操做失敗時拋出異常,另外一種形式返回一個特殊值(null 或 false,具體取決於操做)。插入操做的後一種形式是專爲使用有容量限制的 Deque 實現設計的;在大多數實現中,插入操做不能失敗。設計

下表總結了上述 12 種方法:code

 

  第一個元素(頭部) 最後一個元素(尾部)
  拋出異常 特殊值 拋出異常 特殊值
插入 addFirst(e) offerFirst(e) addLast(e) offerLast(e)
移除 removeFirst() pollFirst() removeLast() pollLast()
檢查 getFirst() peekFirst() getLast() peekLast()

此接口擴展了 Queue 接口。在將雙端隊列用做隊列時,將獲得 FIFO(先進先出)行爲。將元素添加到雙端隊列的末尾,從雙端隊列的開頭移除元素。從 Queue 接口繼承的方法徹底等效於 Deque 方法,以下表所示:

此接口擴展了 Queue 接口。在將雙端隊列用做隊列時,將獲得 FIFO(先進先出)行爲。將元素添加到雙端隊列的末尾,從雙端隊列的開頭移除元素。從 Queue 接口繼承的方法徹底等效於 Deque 方法,以下表所示:

 

Queue 方法 等效 Deque 方法
add(e) addLast(e)
offer(e) offerLast(e)
remove() removeFirst()
poll() pollFirst()
element() getFirst()
peek() peekFirst()

雙端隊列也可用做 LIFO(後進先出)堆棧。應優先使用此接口而不是遺留 Stack 類。在將雙端隊列用做堆棧時,元素被推入雙端隊列的開頭並從雙端隊列開頭彈出。堆棧方法徹底等效於 Deque 方法,以下表所示:

 

堆棧方法 等效 Deque 方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()

注意,在將雙端隊列用做隊列或堆棧時,peek 方法一樣正常工做;不管哪一種狀況下,都從雙端隊列的開頭抽取元素。

此接口提供了兩種移除內部元素的方法:removeFirstOccurrence 和 removeLastOccurrence

與 List 接口不一樣,此接口不支持經過索引訪問元素。

雖然 Deque 實現沒有嚴格要求禁止插入 null 元素,但建議最好這樣作。建議任何事實上容許 null 元素的 Deque 實現用戶最好 要利用插入 null 的功能。這是由於各類方法會將 null 用做特殊的返回值來指示雙端隊列爲空。

Deque 實現一般不定義基於元素的 equals 和 hashCode 方法,而是從 Object 類繼承基於身份的 equals 和 hashCode 方法。

從如下版本開始:
1.6

 

方法摘要
 boolean add(E e) 
          將指定元素插入此雙端隊列所表示的隊列(換句話說,此雙端隊列的尾部),若是能夠直接這樣作而不違反容量限制的話;若是成功,則返回 true,若是當前沒有可用空間,則拋出 IllegalStateException
 void addFirst(E e) 
          將指定元素插入此雙端隊列的開頭(若是能夠直接這樣作而不違反容量限制)。
 void addLast(E e) 
          將指定元素插入此雙端隊列的末尾(若是能夠直接這樣作而不違反容量限制)。
 boolean contains(Object o) 
          若是此雙端隊列包含指定元素,則返回 true
 Iterator<E> descendingIterator() 
          返回以逆向順序在此雙端隊列的元素上進行迭代的迭代器。
 E element() 
          獲取,但不移除此雙端隊列所表示的隊列的頭部(換句話說,此雙端隊列的第一個元素)。
 E getFirst() 
          獲取,但不移除此雙端隊列的第一個元素。
 E getLast() 
          獲取,但不移除此雙端隊列的最後一個元素。
 Iterator<E> iterator() 
          返回以恰當順序在此雙端隊列的元素上進行迭代的迭代器。
 boolean offer(E e) 
          將指定元素插入此雙端隊列所表示的隊列(換句話說,此雙端隊列的尾部),若是能夠直接這樣作而不違反容量限制的話;若是成功,則返回 true,若是當前沒有可用的空間,則返回 false
 boolean offerFirst(E e) 
          在不違反容量限制的狀況下,將指定的元素插入此雙端隊列的開頭。
 boolean offerLast(E e) 
          在不違反容量限制的狀況下,將指定的元素插入此雙端隊列的末尾。
 E peek() 
          獲取,但不移除此雙端隊列所表示的隊列的頭部(換句話說,此雙端隊列的第一個元素);若是此雙端隊列爲空,則返回 null
 E peekFirst() 
          獲取,但不移除此雙端隊列的第一個元素;若是此雙端隊列爲空,則返回 null
 E peekLast() 
          獲取,但不移除此雙端隊列的最後一個元素;若是此雙端隊列爲空,則返回 null
 E poll() 
          獲取並移除此雙端隊列所表示的隊列的頭部(換句話說,此雙端隊列的第一個元素);若是此雙端隊列爲空,則返回 null
 E pollFirst() 
          獲取並移除此雙端隊列的第一個元素;若是此雙端隊列爲空,則返回 null
 E pollLast() 
          獲取並移除此雙端隊列的最後一個元素;若是此雙端隊列爲空,則返回 null
 E pop() 
          今後雙端隊列所表示的堆棧中彈出一個元素。
 void push(E e) 
          將一個元素推入此雙端隊列所表示的堆棧(換句話說,此雙端隊列的頭部),若是能夠直接這樣作而不違反容量限制的話;若是成功,則返回 true,若是當前沒有可用空間,則拋出 IllegalStateException
 E remove() 
          獲取並移除此雙端隊列所表示的隊列的頭部(換句話說,此雙端隊列的第一個元素)。
 boolean remove(Object o) 
          今後雙端隊列中移除第一次出現的指定元素。
 E removeFirst() 
          獲取並移除此雙端隊列第一個元素。
 boolean removeFirstOccurrence(Object o) 
          今後雙端隊列移除第一次出現的指定元素。
 E removeLast() 
          獲取並移除此雙端隊列的最後一個元素。
 boolean removeLastOccurrence(Object o) 
          今後雙端隊列移除最後一次出現的指定元素。
 int size()           返回此雙端隊列的元素數。
相關文章
相關標籤/搜索