Java 集合 Queue

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接口有一个PriorityQueue实现类。除此之外,Queue还有一个Deque接口,Deque代表一个“双端队列”,双端队列可以同时从两端删除、添加元素,因此Deque的实现类既可当成队列使用,也可当成栈使用。Java为Deque提供了ArrayDeque实现类和LinkedList两个实现类

//把ArrayDeque当成栈使用

import java.util.*;

public class ArrayDequeStack
{
    public static void main(String[] args)
    {
        ArrayDeque stack = new ArrayDeque();
        // 依次将三个元素push入"栈"
        stack.push("金州勇士");
        stack.push("俄克拉荷马雷霆");
        stack.push("克利夫兰骑士");
        // 输出:[克利夫兰骑士, 俄克拉荷马雷霆, 金州勇士]
        System.out.println(stack);
        // 访问第一个元素,但并不将其pop出"栈",输出:克利夫兰骑士
        System.out.println(stack.peek());
        // 依然输出:[克利夫兰骑士, 俄克拉荷马雷霆, 金州勇士]
        System.out.println(stack);
        // pop出第一个元素,输出:克利夫兰骑士
        System.out.println(stack.pop());
        // 输出:[俄克拉荷马雷霆, 金州勇士]
        System.out.println(stack);
    }
}


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);
    }
}

实际上,程序多次调用poll()方法,既可看到元素按从小到大的顺序“移出队列”,PriorityQueue队列对元素的要求与TreeSet对元素的要求基本一致

PriorityQueue不允许插入null元素,它还需要对队列元素进行排序,PriorityQueue有两种排序方式

  • 自然排序:采用自然排序的PriorityQueue集合中的元素必须实现Comparator接口,而且应该是一个类的多个实例,否则可能导致ClassCastException异常

  • 定制排序:创建PriorityQueue队列时,传入一个Comparable对象,该对象负责对所有队列中的所有元素进行排序。采用定制排序不要求必须实现Comparator接口

Dueue接口与ArrayDeque实现类

Deque接口

Deque接口是Queue接口的子接口,它代表一个双端队列

  • 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(e)

  • Object removeFirst():获取并删除该双端队列的第一个元素

  • Object removeFirstOccurence(Object o):获取并删除该双端队列的第一次出现的元素o

  • Object removeLast():获取并删除该双端队列的最后一个元素o

  • Object removeLastOccurence(Object o):获取并删除该双端队列的最后一次出现的元素o

  • Deque与Queue的方法对照图

  • Deque与Stack的方法对照图

ArrayDeque实现类

ArrayDeque是一个基于数组实现的双端队列,创建Deque时同样可指定一个numElements参数,该参数用于指定Object[]数组的长度;如果不指定numElements参数,Deque底层数组的长度为16

当程序中需要使用“栈”这种数据结构时,推荐使用ArrayDeque,尽量避免使用Stack——因为Stack是古老的集合,性能较差

//把ArrayDeque当成栈使用

import java.util.*;

public class ArrayDequeStack
{
    public static void main(String[] args)
    {
        ArrayDeque stack = new ArrayDeque();
        // 依次将三个元素push入"栈"
        stack.push("金州勇士");
        stack.push("俄克拉荷马雷霆");
        stack.push("克利夫兰骑士");
        // 输出:[克利夫兰骑士, 俄克拉荷马雷霆, 金州勇士]
        System.out.println(stack);
        // 访问第一个元素,但并不将其pop出"栈",输出:克利夫兰骑士
        System.out.println(stack.peek());
        // 依然输出:[克利夫兰骑士, 俄克拉荷马雷霆, 金州勇士]
        System.out.println(stack);
        // pop出第一个元素,输出:克利夫兰骑士
        System.out.println(stack.pop());
        // 输出:[俄克拉荷马雷霆, 金州勇士]
        System.out.println(stack);
    }
}

ArrayDeque作为队列使用,按“先进先出”的方式操作集合元素

import java.util.*;

public class ArrayDequeQueue
{
    public static void main(String[] args)
    {
        ArrayDeque queue = new ArrayDeque();
        // 依次将三个元素加入队列
        queue.offer("克利夫兰骑士");
        queue.offer("俄克拉荷马雷霆");
        queue.offer("金州勇士");
        // 输出:[克利夫兰骑士, 俄克拉荷马雷霆, 金州勇士]
        System.out.println(queue);
        // 访问队列头部的元素,但并不将其poll出队列"栈",输出:克利夫兰骑士
        System.out.println(queue.peek());
        // 依然输出:[克利夫兰骑士, 俄克拉荷马雷霆, 金州勇士]
        System.out.println(queue);
        // poll出第一个元素,输出:克利夫兰骑士
        System.out.println(queue.poll());
        // 输出:[俄克拉荷马雷霆, 金州勇士]
        System.out.println(queue);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值