Java集合 之 Queue集合


什么是Queue集合?

答:Queue用於模擬隊列這種數據結構。隊列通常是指“先進先出(FIFO)”的容器。隊列的頭部保存在隊列中存放時間最長的元素,尾部保存存放時間最短的元素。新元素插入到隊列的尾部,取出元素會返回隊列頭部的元素。通常,隊列不允許隨機訪問隊列中的元素。

Queue接口中定義了如下的幾個方法:

void add(Object e):  將指定元素插入到隊列的尾部。

object element():  獲取隊列頭部的元素,但是不刪除該元素。

boolean offer(Object e):  將指定的元素插入此隊列的尾部。當使用容量有限的隊列時,此方法通常比add(Object e)有效。 

Object peek():  返回隊列頭部的元素,但是不刪除該元素。如果隊列為空,則返回null。

Object poll():  返回隊列頭部的元素,並刪除該元素。如果隊列為空,則返回null。

Object remove():  獲取隊列頭部的元素,並刪除該元素。

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也是以數組的形式來存儲集合但因為它實現了線程同步(而且實現的機制不好),故各方面的性能都比較差。

 


免責聲明!

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



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