標籤:extends 拋出異常 注意 ali 9.png 隊列實現 介面繼承 建議 inf
queue集合
什麼是Queue集合?
答:Queue用於類比隊列這種資料結構。隊列通常是指“先進先出(FIFO)”的容器。隊列的頭部儲存在隊列中存放時間最長的元素,尾部儲存存放時間最短的元素。
新元素插入到隊列的尾部,取出元素會返回隊列頭部的元素。通常,隊列不允許隨機訪問隊列中的元素。
一、認識queue1、Queue 方法介紹
從上面來看,Queue(隊列)介面繼承自Collection,用來表示內部元素具有先後順序的集合。除了基本的集合操作外,隊列還提供了其他插入、刪除和檢查操作。Queue介面定義如下:
public interface Queue<E> extends Collection<E> { E element(); boolean offer(E e); E peek(); E poll(); E remove(); }
每一個隊列相關方法都提供了兩種形式:一種如果操作失敗拋出異常,另一種如果操作失敗返回一個特殊值(null或false)。
Queue介面結構如所示:
操作 |
拋出異常 |
返回特殊值 |
插入 |
add(e) |
offer(e) |
移除 |
remove() |
poll() |
檢查 |
element() |
peek() |
(1).add(E), offer(E) 在尾部添加:
他們的共同之處是建議實作類別禁止添加 null 元素,否則會報null 指標 NullPointerException;
不同之處在於 add() 方法在添加失敗(比如隊列已滿)時會報 一些執行階段錯誤 錯;而 offer() 方法即使在添加失敗時也不會奔潰,只會返回 false。
(2)remove(), poll() 刪除並返回頭部
當隊列為空白時 remove() 方法會報 NoSuchElementException 錯; 而 poll() 不會奔潰,只會返回 null。
(3)element(), peek() 擷取但不刪除
當隊列為空白時 element() 拋出異常;peek() 不會奔潰,只會返回 null。
2、其它
(1)雖然 LinkedList 沒有禁止添加 null,但是一般情況下 Queue 的實作類別都不允許添加 null 元素,因為 poll(), peek() 方法在異常的時候會返回 null,你添加了 null 以後,當擷取時不好分辨究竟是否正確返回。
(2)Queue 一般都是 FIFO 的,但是也有例外,比如優先隊列 priority queue(它的順序是根據自然排序或者自訂 comparator 的);再比如 LIFO 的隊列(跟棧一樣,後來進去的先出去)。
(3)不論進入、出去的先後順序是怎樣的,使用 remove(),poll() 方法操作的都是 頭部 的元素;而插入的位置則不一定是在隊尾了,不同的 queue 會有不同的插入邏輯。
二、PriorityQueue實作類別
PriorityQueue是一個比較標準的隊列實作類別。PriorityQueue儲存隊列元素的順序並不是按排入佇列的順序,而是按隊列元素的大小進行重新排列。因此當調用peek()方法或者poll()方法取出隊
列中的元素時,並不是取出最先進入隊列的元素,而是取出隊列中最小的元素。
1、PriorityQueue的排序方式
PriorityQueue中的元素可以預設自然排序(也就是數字預設是小的在隊列頭,字串則按字典序排列)或者通過提供的Comparator(比較子)在隊列執行個體化時指定的排序方式。
(1)小案例
PriorityQueue<Integer> qi = new PriorityQueue<Integer>(); qi.offer(5); qi.offer(2); qi.offer(1); qi.offer(10); qi.offer(3); while (!qi.isEmpty()){ System.out.print(qi.poll() + ","); } System.out.println(); //採用降序排列的方式,越小的越排在隊尾 Comparator<Integer> cmp = new Comparator<Integer>() { public int compare(Integer e1, Integer e2) { return e2 - e1; } }; //這裡是初始容量3,當我們超過3個會自動擴容,所以說它是個無邊界容器 PriorityQueue<Integer> q2 = new PriorityQueue<Integer>(3,cmp); q2.offer(2); q2.offer(8); q2.offer(9); q2.offer(1); while (!q2.isEmpty()){ System.out.print(q2.poll() + ","); }
輸出結果:
由此可以看出,預設情況下PriorityQueue採用自然排序。指定Comparator的情況下,PriorityQueue採用指定的排序方式。
注意:當PriorityQueue中沒有指定Comparator時,加入PriorityQueue的元素必須實現了Comparable介面(即元素是可比較的),否則會導致 ClassCastException。
(比如你放入的是對象,那麼必須指定Comparator,因為對象是無法比較的)
2、 PriorityQueue特性
(1)隊列元素根據自然排序或者根據具體的比較子排序
(2)執行個體化時若未指定初始容量,預設容量為11
(3)自動擴容。如果容量小於64,兩倍增長擴容;否則增長50%
(4)無邊界容器
(5)不支援null元素
(6)非安全執行緒
(7)支援被序列化
(8)入隊出隊的時間複雜度O(log(n))
有關Dueue介面與ArrayDeque實作類別和LinkedList實作類別以後用到了再寫他們。
現在只要知道:
(1)Deque介面是Queue介面的子介面,它代表一個雙端隊列。
(2)LinkedList是List介面的實作類別,因此它可以是一個集合,可以根據索引來隨機訪問集合中的元素。此外,它還是Duque介面的實作類別,因此也可以作為一個雙端隊列,或者棧來使用。
想太多,做太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多做。少校【13】
【java提高】---queue集合