队列(Queue
)是用于在处理之前保存元素的集合。除了基本的Collection
操作外,队列还提供其他插入,移除和检查操作。队列接口如下。
public interface Queue<E> extends Collection<E> {
E element();
boolean offer(E e);
E peek();
E poll();
E remove();
}
每种Queue
方法都以两种形式存在:(1)一种方法在操作失败时抛出异常,(2)另一种方法在操作失败时返回一个特殊值(null
或false
,取决于操作)。下表说明了接口的常规结构 。
队列接口结构
操作类型 | 抛出异常 | 返回特殊值 |
---|---|---|
插入 | add(e) |
offer(e) |
去掉 | remove() |
poll() |
检查 | element() |
peek() |
队列通常但不是必须以FIFO(先进先出)的方式对元素进行排序。优先级队列是例外,它们根据元素的值对元素进行排序——有关详细信息,请参见“对象排序”部分。无论使用哪种排序,队列的开头都是将通过调用remove
或poll
删除的元素。在FIFO队列中,所有新元素都插入到队列的尾部。其他种类的队列可能使用不同的放置规则。每个Queue
实现必须指定其排序属性。Queue
实现有可能限制其持有的元素数量;这样的队列称为有界队列。java.util.concurrent
中的某些Queue
实现是有界的,但java.util
中的某些实现不受限制。Queue
继承自Collection
的add
方法将插入一个元素,除非该方法违反队列的容量限制,在这种情况下,它将抛出IllegalStateException
。offer
方法仅用于有界队列,它与add
的区别仅在于add
方法,它通过返回false
指示无法插入元素。remove
和poll
方法都删除并返回队列的头部。究竟要删除哪个元素是队列的排序策略的函数。仅当队列为空时,remove
和poll
方法的行为不同。在这种情况下,remove
抛出NoSuchElementException
,而poll
返回null
。element
和peek
方法返回但不删除队列的开头。它们以与remove
和poll
完全相同的方式彼此不同:如果队列为空,则element
抛出NoSuchElementException
,而peek
返回null
。
队列实现通常不允许插入空元素。改型为实现Queue
的LinkedList
实现是一个例外。出于历史原因,它允许使用null
元素,但是您应避免利用它,因为poll
和peek
方法将null
用作特殊的返回值。
队列实现通常不定义equals
和hashCode
方法的基于元素的版本,而是从Object
继承基于身份的版本。
队列接口没有定义并发编程中常见的阻塞队列方法。这些方法等待元素出现或空间可用,这些方法在接口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> heapSort(Collection<E> c) {
Queue<E> queue = new PriorityQueue<E>(c);
List<E> result = new ArrayList<E>();
while (!queue.isEmpty())
result.add(queue.remove());
return result;
}