文档

Java™教程
隐藏目录
队列接口
路径: 集合
课程: 接口

队列接口

一个Queue是在处理之前保存元素的集合。除了基本的Collection操作外,队列还提供了额外的插入、删除和检查操作。以下是Queue接口的定义。

public interface Queue<E> extends Collection<E> {
    E element();
    boolean offer(E e);
    E peek();
    E poll();
    E remove();
}

每个Queue方法都有两种形式:(1)如果操作失败,抛出异常;(2)如果操作失败,则返回一个特殊值(根据操作的不同,可以是nullfalse)。接口的常规结构如下表所示。

队列接口结构
操作类型 抛出异常 返回特殊值
插入 add(e) offer(e)
删除 remove() poll()
查看 element() peek()

队列通常(但不一定)以先进先出(FIFO)的方式对元素进行排序。优先级队列是一种例外,它根据元素的值进行排序 - 详见对象排序部分)。无论使用什么排序方式,队列的头部元素是通过调用removepoll方法来删除的。在FIFO队列中,所有新元素都插入到队列的尾部。其他类型的队列可能使用不同的插入规则。每个Queue实现都必须指定其排序属性。

Queue实现可以限制它所保存的元素数量;这种队列称为有界队列。一些java.util.concurrent中的Queue实现是有界的,但java.util中的实现不是。

add方法是QueueCollection继承的,它插入一个元素,除非它违反了队列的容量限制,否则会抛出IllegalStateException异常。offer方法只用于有界队列,与add方法的区别在于它通过返回false来表示插入元素失败。

removepoll方法都会移除并返回队列的头部元素。具体移除的是哪个元素是由队列的排序策略决定的。当队列为空时,remove方法会抛出NoSuchElementException异常,而poll方法会返回null

elementpeek方法返回队列的头部元素,但不会将其移除。它们与removepoll的区别与之相同:如果队列为空,element方法会抛出NoSuchElementException异常,而peek方法会返回null

Queue实现通常不允许插入null元素。但是,LinkedList实现是一个例外,它被改造成实现Queue接口,并允许插入null元素,但你应该避免利用这一点,因为pollpeek方法会将null作为特殊返回值。

Queue实现通常不定义基于元素的equalshashCode方法,而是继承自Object的基于身份的版本。

Queue接口没有定义阻塞队列方法,这在并发编程中很常见。这些方法等待元素出现或可用空间,它们被定义在接口java.util.concurrent.BlockingQueue中,该接口扩展了Queue接口。

在下面的示例程序中,使用队列实现了一个倒计时器。队列会预先加载从命令行指定的数字到零的所有整数值,按照降序排列。然后,这些值会在一秒的时间间隔内从队列中移除并打印出来。这个程序是人为的,因为在没有使用队列的情况下做同样的事情更自然,但它展示了在后续处理之前使用队列存储元素的用法。

import java.util.*;

public class Countdown {
    public static void main(String[] args) throws InterruptedException {
        int time = Integer.parseInt(args[0]);
        Queue<Integer> queue = new LinkedList<Integer>();

        for (int i = time; i >= 0; i--)
            queue.add(i);

        while (!queue.isEmpty()) {
            System.out.println(queue.remove());
            Thread.sleep(1000);
        }
    }
}

在下面的示例中,使用优先队列对一组元素进行排序。同样,这个程序是人为的,在使用Collections中提供的sort方法更好的情况下,没有理由使用它,但它展示了优先队列的行为。

static <E> List<E> 堆排序(Collection<E> c) {
    Queue<E> 队列 = new PriorityQueue<E>(c);
    List<E> 结果 = new ArrayList<E>();

    while (!队列.isEmpty())
        结果.add(队列.remove());

    return 结果;
}

上一页: 列表接口
下一页: 双端队列接口