Java中的queue和deque對比詳解


隊列(queue)簡述

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

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

 

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

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

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

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),遵循先進后出原則。

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

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

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

 

  第一個元素(頭部) 最后一個元素(尾部)
  拋出異常 特殊值 拋出異常 特殊值
插入 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() 
          返回此雙端隊列的元素數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM