概述

队列也是一种操作受限的线性结构。它与栈相反是先进先出(FIFO—first in first out),只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作,与我们生活中排队一样。

术语 说明
队尾 进行插入操作的端成为队尾
对头 进行删除操作的端成为对头
入队/enqueue 在队列尾部插入一个元素
出队/dequeue 从队头中取一个元素
  1. public interface Queue<E> {
  2. int getSize();
  3. boolean isEmpty();
  4. void enqueue(E e);
  5. E dequeue();
  6. E getFront();
  7. }

单向队列(Queue)

只能在一端插入数据,另一端删除数据。

  1. import java.util.ArrayList;
  2. public class ArrayQueue<E> implements Queue<E> {
  3. private ArrayList<E> list;
  4. public ArrayQueue() {
  5. list = new ArrayList<>();
  6. }
  7. @Override
  8. public int getSize() {
  9. return list.size();
  10. }
  11. @Override
  12. public boolean isEmpty() {
  13. return list.isEmpty();
  14. }
  15. @Override
  16. public void enqueue(E e) {
  17. list.add(e);
  18. }
  19. @Override
  20. public E dequeue() {
  21. if (!isEmpty()) {
  22. return list.remove(list.size() - 1);
  23. }
  24. return null;
  25. }
  26. @Override
  27. public E getFront() {
  28. if (!isEmpty()) {
  29. return list.get(0);
  30. }
  31. return null;
  32. }
  33. @Override
  34. public String toString() {
  35. return list.toString();
  36. }
  37. }

循环队列

Java队列API

图片.png

Queue的插入操作

  1. /**
  2. * 相同点:
  3. * 插入为null的元素,会报空指针
  4. * 插入与执行泛型不符的类型会报类型转换异常
  5. * 插入某些不允许插入的元素,会阻止其插入,IDE会提示非法参数
  6. *
  7. * 不同点:
  8. * 在满队列状态下:
  9. * 使用add()方法会报IllegalStateException异常,提示队列已满.
  10. * 使用offer()方法在此情况下不会报异常而返回false.
  11. */
  12. boolean add(E e);
  13. boolean offer(E e);

上述两种方法都是插入操作,当插入元素成功时,会返回true.注意 : 队列中不允许插入为null的元素,否则会报空指针.在进行插入操作时,一般情况推荐使用offer()来插入元素.

Queue的取出操作

  1. /**
  2. * 相同点:
  3. * 都是Queue的取出操作,返回值为队列容器头部元素.
  4. *
  5. * 不同点:
  6. * 当处于空队列状态时,remove()方法会抛出队列为空,没有匹配元素的的异常
  7. * 而poll()方法则会返回null值,不会报异常.
  8. */
  9. E remove();
  10. E poll();

在进行删除操作时,一般情况推荐使用poll()来取出元素

Queue的检索操作

  1. /**
  2. * 相同点:
  3. * 都是Queue的检索操作,返回值为队列容器头部元素,但是不会删除元素.
  4. *
  5. * 不同点:
  6. * 当处于空队列状态时,element()方法会抛出队列为空,没有匹配元素的的异常
  7. * 而peek()方法则会返回null值,不会报异常.
  8. */
  9. E element();
  10. E peek();

在进行检索操作时,一般情况推荐使用peek()来取出元素

双向队列/double ended queue

Deque是一种具有队列和栈的性质的数据结构.双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行.
通过开始的类图可以发现,Deque继承了Queue(队列)的接口,它的直接实现有ArrayDeque、LinkedList等。
Deque的容量有两种模式,一种是固定长度,另一种是容量无限。
同Queue一样,Deque也定义了两套操作访问元素的方法,比如在头部和尾部进行插入、删除、检索元素、同样的,一种是在满队列或者空队列的操作元素时,会报异常,而另一种则会return null或者return false。
LinkedList 大小可变的链表双端队列,允许元素为 null
ArrayDeque 大下可变的数组双端队列,不允许 null
注意:LinkedList 和ArrayDeque是线程不安全的容器。
在并发场景下,推荐使用LinkedBlockingDeque:因为LinkedBlockingDeque在队列为空的情况下,获取操作将会阻塞,直到有元素添加。