Queue接口
Queue是在處理之前保存元素的集合,除了基本的Collection
操作外,隊列還提供額外的插入、刪除和檢查操作,Queue
接口如下。
public interface Queue<E> extends Collection<E> {E element();boolean offer(E e);E peek();E poll();E remove();
}
每個Queue
方法都有兩種形式:(1)如果操作失敗則拋出異常,(2)如果操作失敗,則返回特殊值(null
或false
,具體取決于操作),接口的常規結構如下表所示。
操作類型 | 拋出異常 | 返回特殊值 |
---|---|---|
插入 | add(e) | offer(e) |
移除 | remove() | poll() |
檢查 | element() | peek() |
隊列通常(但不一定)以FIFO(先進先出)方式對元素進行排序,優先級隊列除外,它們根據元素的值對元素進行排序 — 有關詳細信息,請參閱“對象排序”部分。無論使用什么排序,隊列的頭部都是通過調用remove
或poll
移除的元素。在FIFO隊列中,所有新元素都插入隊列的尾部,其他類型的隊列可能使用不同的放置規則,每個Queue
實現都必須指定其排序屬性。
Queue
實現可以限制它所擁有的元素數量,這樣的隊列被稱為有界,java.util.concurrent
中的某些Queue
實現是有界的,但java.util
中的實現不是。
Queue
從Collection
繼承的add
方法插入一個元素,除非它違反了隊列的容量限制,在這種情況下它會拋出IllegalStateException
。offer
方法,僅用于有界隊列,與add
不同之處僅在于它通過返回false
來表示插入元素失敗。
remove
和poll
方法都移除并返回隊列的頭部,確切地移除哪個元素是隊列的排序策略的函數,僅當隊列為空時,remove
和poll
方法的行為才有所不同,在這些情況下,remove
拋出NoSuchElementException
,而poll
返回null
。
element
和peek
方法返回但不移除隊列的頭部,它們之間的差異與remove
和poll
的方式完全相同:如果隊列為空,則element
拋出NoSuchElementException
,而peek
返回null
。
隊列實現通常不允許插入null
元素,為實現Queue
而進行了改進的LinkedList
實現是一個例外,由于歷史原因,它允許null
元素,但是你應該避免利用它,因為null
被poll
和peek
方法用作特殊的返回值。
隊列實現通常不定義equals
和hashCode
方法的基于元素的版本,而是從Object
繼承基于標識的版本。
Queue
接口不定義阻塞隊列方法,這在并發編程中很常見,這些等待元素出現或空間可用的方法在java.util.concurrent.BlockingQueue接口中定義,該接口擴展了Queue
。
在以下示例程序中,隊列用于實現倒數計時器,隊列預先加載了從命令行上指定的數字到0的所有整數值,按降序排列,然后,從隊列中刪除值并以一秒的間隔打印。該程序是人為的,因為在不使用隊列的情況下執行相同的操作會更自然,但它說明了在后續處理之前使用隊列來存儲元素。
import java.util.*;public class Countdown {public static void main(String[] args) throws InterruptedException {int time = Integer.parseInt(args[0]);Queue<Integer> queue = new LinkedList<Integer>();for (int i = time; i >= 0; i--)queue.add(i);while (!queue.isEmpty()) {System.out.println(queue.remove());Thread.sleep(1000);}}
}
在以下示例中,優先級隊列用于對元素集合進行排序,同樣,這個程序是人為的,因為沒有理由使用它來支持集合中提供的排序方法,但它說明了優先級隊列的行為。
static <E> List<E> heapSort(Collection<E> c) {Queue<E> queue = new PriorityQueue<E>(c);List<E> result = new ArrayList<E>();while (!queue.isEmpty())result.add(queue.remove());return result;
}