什麼是Queue集合?java
答:Queue用於模擬隊列這種數據結構。隊列一般是指「先進先出(FIFO)」的容器。隊列的頭部保存在隊列中存放時間最長的元素,尾部保存存放時間最短的元素。新元素插入到隊列的尾部,取出元素會返回隊列頭部的元素。一般,隊列不容許隨機訪問隊列中的元素。數組
Queue接口中定義了以下的幾個方法:數據結構
void add(Object e): 將指定元素插入到隊列的尾部。性能
object element(): 獲取隊列頭部的元素,可是不刪除該元素。spa
boolean offer(Object e): 將指定的元素插入此隊列的尾部。當使用容量有限的隊列時,此方法一般比add(Object e)有效。 線程
Object peek(): 返回隊列頭部的元素,可是不刪除該元素。若是隊列爲空,則返回null。3d
Object poll(): 返回隊列頭部的元素,並刪除該元素。若是隊列爲空,則返回null。指針
Object remove(): 獲取隊列頭部的元素,並刪除該元素。code
Queue接口有一個PriorityQueue實現類。除此以外,Queue還有一個Deque接口,Deque表明一個「雙端隊列」,雙端隊列能夠同時從兩端刪除或添加元素,所以Deque能夠看成棧來使用。java爲Deque提供了ArrayDeque實現類和LinkedList實現類。對象
1.PriorityQueue實現類
PriorityQueue是一種比較標準的隊列實現類,而不是絕對標準的。這是由於PriorityQueue保存隊列元素的順序不是按照元素添加的順序來保存的,而是在添加元素的時候對元素的大小排序後再保存的。所以在PriorityQueue中使用peek()或pool()取出隊列中頭部的元素,取出的不是最早添加的元素,而是最小的元素。
public class PriorityQueueTest { public static void main(String[] args){ PriorityQueue pq = new PriorityQueue(); pq.offer(6); pq.add(-3); pq.add(20); pq.offer(18); //輸出:[-3, 6, 20, 18] System.out.println(pq); } }
PriorityQueue不容許插入null元素,它還須要對隊列元素進行排序,PriorityQueue有兩種排序方式:
天然排序:採用天然排序的PriorityQueue集合中的元素必須實現Comparator接口,並且應該是一個類的多個實例,不然可能致使ClassCastException異常。
定製排序:建立PriorityQueue隊列時,傳入一個Comparable對象,該對象負責對全部隊列中的全部元素進行排序。採用定製排序不要求必須實現Comparator接口。
2.Dueue接口與ArrayDeque實現類
Deque接口是Queue接口的子接口,它表明一個雙端隊列,Deque定義了一些方法:
void addFirst(Object e): 將指定元素添加到雙端隊列的頭部。
void addLast(Object e): 將指定元素添加到雙端隊列的尾部。
Iteratord descendingItrator(): 返回該雙端隊列對應的迭代器,該迭代器以逆向順序來迭代隊列中的元素。
Object getFirst(): 獲取但不刪除雙端隊列的第一個元素。
Object getLast(): 獲取但不刪除雙端隊列的最後一個元素。
boolean offFirst(Object e): 將指定元素添加到雙端隊列的頭部。
boolean offLast(OBject e): 將指定元素添加到雙端隊列的尾部。
Object peekFirst(): 獲取但不刪除雙端隊列的第一個元素;若是雙端隊列爲空,則返回null。
Object PeekLast(): 獲取但不刪除雙端隊列的最後一個元素;若是雙端隊列爲空,則返回null。
Object pollFirst(): 獲取並刪除雙端隊列的第一個元素;若是雙端隊列爲空,則返回null。
Object pollLast(): 獲取並刪除雙端隊列的最後一個元素;若是雙端隊列爲空,則返回null。
Object pop()(棧方法): pop出該雙端隊列所表示的棧的棧頂元素。至關於removeFirst()。
void push(Object e)(棧方法): 將一個元素push進該雙端隊列所表示的棧的棧頂。至關於addFirst()。
Object removeFirst(): 獲取並刪除該雙端隊列的第一個元素。
Object removeFirstOccurence(Object o): 刪除該雙端隊列的第一次出現的元素o。
Object removeLast(): 獲取並刪除該雙端隊列的最後一個元素o。
Object removeLastOccurence(Object o): 刪除該雙端隊列的最後一次出現的元素o。
public class ArrayDequeTest { public static void main(String[] args){ ArrayDeque queue = new ArrayDeque(); queue.offer("春"); queue.offer("夏"); queue.offer("秋"); //輸出:[春, 夏, 秋] System.out.println(queue); //輸出:春 System.out.println(queue.peek()); //輸出:[春, 夏, 秋] System.out.println(queue); //輸出:春 System.out.println(queue.poll()); //輸出:[夏, 秋] System.out.println(queue); } }
//將雙端隊列當作棧 public class DequeStack { public static void main(String[] args){ ArrayDeque stack = new ArrayDeque(); stack.push("春"); stack.push("夏"); stack.push("秋"); //輸出:[秋, 夏, 春] System.out.println(stack); //輸出:秋 System.out.println(stack.peek()); //輸出:[秋, 夏, 春] System.out.println(stack); //輸出:秋 System.out.println(stack.pop()); //輸出:[夏, 春] System.out.println(stack); } }
3.LinkedList實現類
LinkedList是List接口的實現類,所以它能夠是一個集合,能夠根據索引來隨機訪問集合中的元素。此外,它仍是Duque接口的實現類,所以也能夠做爲一個雙端隊列,或者棧來使用。
LinkedList與ArrayList,ArrayDeque的實現機制徹底不一樣,ArrayList和ArrayDeque內部以數組的形式來保存集合中的元素,所以隨機訪問集合元素時有較好的性能;而LinkedList以鏈表的形式來保存集合中的元素,所以隨機訪問集合元素時性能較差,可是插入和刪除元素時性能比較出色(只需改變指針所指的地址便可),須要指出的是,雖然Vector也是以數組的形式來存儲集合但由於它實現了線程同步(並且實現的機制很差),故各方面的性能都比較差。