標籤:方法 eset ast 調用 方式 訪問 new print list介面
Queue用於類比了隊列這種資料結構,隊列通常是指“先進先出”(FIFO)的容器。隊列的頭部儲存在隊列中時間最長的元素,隊列的尾部儲存在隊列中時間最短的元素。新元素插入(offer)到隊列的尾部,訪問元素(poll)操作會返回隊列頭部的元素。通常,隊列不容許隨機訪問隊列中的元素。
Queue介面中定義了如下幾個方法:
- void add(Object e); //將指定元素加入此隊列的尾部。
- Object element(); //擷取隊列頭部的元素,但是不刪除該元素。
- boolean offer(Object e); //將指定元素加入此隊列的尾部。當使用有容量限制的隊列時,此方法通常比add(Object e)方法更好。
- Object peek(); //擷取隊列頭部的元素,但是不刪除該元素,如果此隊列為空白,則返回null。
- Object poll(); //擷取隊列頭部的元素,並刪除該元素,如果此隊列為空白,則返回null。
- Object remove(); //擷取隊列頭部的元素,並刪除該元素。
Queue有兩個常用的實作類別:LinkedList和PriorityQueue,下面分別介紹這兩個實作類別。
LinkedList類是一個比較奇怪的類,它即是List介面的實作類別,這意味著它是一個List集合,可以根據索引來隨機訪問集合中的元素。除此之外,LinkedList還實現了Deque介面,Deque介面是Queue介面的子介面,它代表一個雙向隊列,Deque介面裡定義了一些可以雙向操作隊列的方法:
- void addFirst(Object e); //將指定元素插入該雙向隊列的開頭。
- void addLast(Object e); //將指定元素插入該雙向隊列的末尾。
- Iterator descendingIterator(); //返回以該雙向隊列對應的迭代器,該迭代器將以逆向順序來迭代隊列中的元素。
- Object getFirst(); //擷取、但不刪除雙向隊列的第一個元素。
- Object getLast(); //擷取、但不刪除雙向隊列的最後一個元素。
- boolean offerFirst(Object e);//將指定元素插入該雙向隊列的開頭
- boolean offerLast(Object e);//將指定元素插入該雙向隊列的結尾
- Object peekFirst(); //擷取、但不刪除雙向隊列的第一個元素;如果此雙端隊列為空白,則返回null。
- Object peekLast(); //擷取、但不刪除該雙向隊列的最後一個元素;如果此雙端隊列為空白,則返回null。
- Object pollFirst(); //擷取、並刪除雙向隊列的第一個元素;如果此雙端隊列為空白,則返回null。
- Object pollLast(); //擷取、並刪除雙向隊列的最後一個元素,如果此雙端隊列為空白,則返回null。
- Object pop(); //pop出該雙向隊列所表示的棧中第一個元素。
- void push(Object e); //將一個元素push進該雙向隊列所表示的棧中。
- Object removeFirst(); //擷取、並刪除該雙向隊列的第一個元素。
- Object removeFirstOccurrence(Object e); //刪除該雙向隊列的第一次的出現元素e。
- removeLast(); //擷取、並刪除該雙向隊列的最後一個元素。
- removeLastOccurrence(Object e); //刪除該雙向隊列的最後一次的出現元素e
從以上方法可以看出,LinkedList不僅可以當成雙向隊列使用,也可以當成“棧”使用,因為該類還包含了pop(出棧)和push(入棧)兩個方法。除此之外,LinkedList實現了List介面,所以還被當成List使用。
*建議:
- 如果需要遍曆List集合元素,對於ArrayList、Vector集合,則應該使用隨機存取方法(get)來遍曆集合元素,這樣效能更好,對於LinkedList集合,則應該採用迭代器(Iterater)來遍曆集合元素。
- 如果需要經常執行插入、刪除操作來改變List集合大小,則應該使用LinkedList集合,而不是ArrayList。使用ArrayList、Vector集合將需要經常重新分配記憶體數組的大小,其時間開銷往往是使用LinkedList時時間開銷的幾十倍,效果很差。
- 如果有多條線程需要同時訪問List集合中的元素,可以考慮使用Vector這個同步實現。
PriorityQueue是一個比較標準的隊列實作類別,之所以說它是比較標準的隊列實現,而不是絕對標準的隊列實現是因為:PriorityQueue儲存隊列元素的順序並不是按排入佇列的順序,而是按隊列元素的大小進行重新排序。因此當調用peek方法活著pull方法來取出隊列中的元素時,並不是取出最先進入隊列的元素,而是取出隊列中最小的元素。從這個意義上看,PriorityQueue已經違反了隊列的最基本原則:先進先出(FIFO)。下面程式示範了PriorityQueue隊列的用法。
public class Test { public static void main(String[] args){ PriorityQueue<Integer> pq = new PriorityQueue<Integer>(); pq.offer(3); pq.offer(-6); pq.offer(9); //列印結果為[-6, 3, 9] System.out.println(pq); //列印結果為-6 System.out.println(pq.peek()); //列印結果為-6 System.out.println(pq.poll()); }}
PriorityQueue不允許插入null元素,它還需要對隊列元素進行排序,隊列元素有兩種排序方式:自然排序、定製排序; 關於使用自然排序和定製排序與前面講到的TreeSet集合一樣,讀者可以查看Java集合(二)這章的內容
Java集合架構(四)—— Queue、LinkedList、PriorityQueue