先进先出队列(简称队列)是一种基于先进先出(FIFO)策略的集合类型。可以使用数组和链表实现。
API
| 成员函数(Item 是泛型变量) | 功能 | 
|---|---|
| Queue() | 创建空队列 | 
| void enqueue() | 添加一个元素 | 
| Item dequeue() | 删除最早添加的元素 | 
| boolean isEmpty() | 队列是否为空 | 
| int size() | 队列中的元素数量 | 
实现
两种实现都支持 forEach 迭代。
数组实现
import java.util.Iterator;import java.util.NoSuchElementException;import java.util.Random;public class ResizingArrayQueue<Item> implements Iterable<Item> {// 初始化队列数组大小private static final int INIT_CAPACITY = 8;// 队列元素数组private Item[] q;// 当前队列的元素数量private int n;// 队列头部元素private int first;// 队列尾部元素private int last;/*** 初始化空队列*/public ResizingArrayQueue() {q = (Item[]) new Object[INIT_CAPACITY];n = 0;first = 0;last = 0;}/*** 当前队列是否为空** @return 为空返回 true,否则放回 false*/public boolean isEmpty() {return n == 0;}/*** 当前队列的元素数量** @return 元素数量*/public int size() {return n;}/*** 动态调整队列数组大小** @param capacity*/private void resize(int capacity) {assert capacity >= n;Item[] copy = (Item[]) new Object[capacity];for (int i = 0; i < n; i++) {copy[i] = q[(first + i) % q.length];}q = copy;first = 0;last = n;}/*** 添加一个元素** @param item*/public void enqueue(Item item) {if (n == q.length) resize(2 * q.length);q[last++] = item;if (last == q.length) last = 0;n++;}/*** 删除队列最早添加的元素** @return 队列最早添加的元素*/public Item dequeue() {if (isEmpty()) throw new NoSuchElementException("Queue underflow");Item item = q[first];q[first] = null;n--;first++;if (first == q.length) first = 0;if (n > 0 && n == q.length / 4) resize(q.length / 2);return item;}/*** 查看队列最早添加元素(不删除)** @return 队列最早添加的元素*/public Item peek() {if (isEmpty()) throw new NoSuchElementException("Queue underflow");return q[first];}/*** forEach 迭代** @return*/public Iterator<Item> iterator() {return new ArrayIterator();}private class ArrayIterator implements Iterator<Item> {private int i = 0;public boolean hasNext() {return i < n;}public void remove() {throw new UnsupportedOperationException();}public Item next() {if (!hasNext()) throw new NoSuchElementException();Item item = q[(i + first) % q.length];i++;return item;}}public static void main(String[] args) {ResizingArrayQueue<String> queue = new ResizingArrayQueue<>();for (int i = 0; i < 8; i++) {// generator random stringint leftLimit = 97; // letter 'a'int rightLimit = 122; // letter 'z'int targetStringLength = 3;Random random = new Random();String generatedString = random.ints(leftLimit, rightLimit + 1).limit(targetStringLength).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();queue.enqueue(generatedString);}System.out.println("isEmpty: " + queue.isEmpty());System.out.println("size: " + queue.size());System.out.println("peek: " + queue.peek());System.out.println();for (String s : queue) {System.out.println("str: " + s);}}}
其中在 resize() 和 next() 方法中有这么一句代码:
Item item = q[(i + first) % q.length];
还有 enqueue() 和 dequeue() 中的代码:
if (last == q.length) last = 0; // enqueue()if (first == q.length) first = 0; // dequeue()
对应的是这种情况:

链表实现
package chapter1.c1_3;import java.util.Iterator;import java.util.NoSuchElementException;import java.util.Random;public class LinkedQueue<Item> implements Iterable<Item> {private int n;private Node first;private Node last;/*** 内部结点类*/private class Node {private Item item;private Node next;}/*** 初始化空栈*/private LinkedQueue() {first = null;last = null;n = 0;assert check();}/*** 是否为空栈** @return 为空返回 true,否则返回 false*/public boolean isEmpty() {return first == null;}public int size() {return n;}/*** 查看最早添加的元素(不删除)** @return 最早添加的元素*/public Item peek() {if (isEmpty()) throw new NoSuchElementException("Queue underflow");return first.item;}/*** 添加一个元素** @param item*/public void enqueue(Item item) {Node oldLast = last;last = new Node();last.item = item;last.next = null;if (isEmpty()) first = last;else oldLast.next = last;n++;assert check();}/*** 删除最早添加的元素** @return 最早添加的元素*/public Item dequeue() {if (isEmpty()) throw new NoSuchElementException("Queue underflow");Item item = first.item;first = first.next;n--;if (isEmpty()) last = null;assert check();return item;}/*** 元素转化为字符串** @return 字符串*/public String toString() {StringBuilder s = new StringBuilder();for (Item item : this) {s.append(item).append(" ");}return s.toString();}/*** 检测内部变量** @return 全部通过返回 true,否则返回 false*/public boolean check() {if (n < 0) {return false;} else if (n == 0) {if (first != null) return false;return last == null;} else if (n == 1) {if (first == null || last == null) return false;if (first != last) return false;return first.next == null;} else {if (first == null || last == null) return false;if (first == last) return false;if (first.next == null) return false;if (last.next != null) return false;int numberOfNodes = 0;for (Node x = first; x != null && numberOfNodes <= n; x = x.next) {numberOfNodes++;}if (numberOfNodes != n) return false;Node lastNode = first;while (lastNode.next != null) {lastNode = lastNode.next;}return last == lastNode;}}/*** 支持 forEach 迭代** @return*/@Overridepublic Iterator<Item> iterator() {return new LinkedIterator();}private class LinkedIterator implements Iterator<Item> {private Node current = first;@Overridepublic boolean hasNext() {return current != null;}@Overridepublic Item next() {if (!hasNext()) throw new NoSuchElementException();Item item = current.item;current = current.next;return item;}@Overridepublic void remove() {throw new UnsupportedOperationException();}}public static void main(String[] args) {ResizingArrayQueue<String> queue = new ResizingArrayQueue<>();for (int i = 0; i < 8; i++) {// generator random stringint leftLimit = 97; // letter 'a'int rightLimit = 122; // letter 'z'int targetStringLength = 3;Random random = new Random();String generatedString = random.ints(leftLimit, rightLimit + 1).limit(targetStringLength).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();queue.enqueue(generatedString);}System.out.println("isEmpty: " + queue.isEmpty());System.out.println("size: " + queue.size());System.out.println("peek: " + queue.peek());System.out.println();for (String s : queue) {System.out.println("str: " + s);}}}
对应的图:

附件:
LinkedQueue.drawioResizingArrayStack.drawio
参考:
