Java Queue 与 Deque
Queue(队列)和 Deque(双端 队列)是 Java 集合框架中用于实现队列数据结构的接口。理解队列的使用是处理 FIFO 和双端操作的基础。本章将详细介绍 Java 中的队列。
Queue 接口与实现(LinkedList、PriorityQueue)
Queue 接口
**Queue**是队列接口,遵循 FIFO(First In First Out,先进先出)原则。
核心方法:
| 操作 | 抛出异常 | 返回特殊值 |
|---|---|---|
| 插入 | add(e) | offer(e) |
| 删除 | remove() | poll() |
| 查看 | element() | peek() |
LinkedList 作为 Queue
LinkedList 实现了 Queue 接口,可以作为队列使用。
import java.util.LinkedList;
import java.util.Queue;
Queue<String> queue = new LinkedList<>();
// 添加元素(推荐使用 offer)
queue.offer("first");
queue.offer("second");
queue.offer("third");
// 查看队首元素(不删除)
String head = queue.peek(); // "first"
// 删除并返回队首元素
String removed = queue.poll(); // "first"
PriorityQueue( 优先级队列)
**PriorityQueue**是基于堆实现的优先级队列,元素按优先级排序。
import java.util.PriorityQueue;
// 自然排序(升序)
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(3);
pq.offer(1);
pq.offer(4);
pq.offer(1);
pq.offer(5);
// 按优先级取出(最小的先出)
while (!pq.isEmpty()) {
System.out.println(pq.poll()); // 1, 1, 3, 4, 5
}
// 自定义排序(降序)
PriorityQueue<Integer> pqDesc = new PriorityQueue<>(Collections.reverseOrder());
pqDesc.offer(3);
pqDesc.offer(1);
pqDesc.offer(4);
while (!pqDesc.isEmpty()) {
System.out.println(pqDesc.poll()); // 4, 3, 1
}
Queue 的常用方法
Queue<String> queue = new LinkedList<>();
// 添加元素
boolean added = queue.offer("item"); // 推荐:返回 boolean
// queue.add("item"); // 不推荐:失败时抛出异常
// 删除元素
String removed = queue.poll(); // 推荐:返回 null(如果为空)
// String removed = queue.remove(); // 不推荐:失败时抛出异常
// 查看元素
String head = queue.peek(); // 推荐:返回 null(如果为空)
// String head = queue.element(); // 不推荐:失败时抛出异常
// 检查
boolean empty = queue.isEmpty();
int size = queue.size();
Deque 接口(ArrayDeque)
Deque 接口
**Deque(Double Ended Queue)**是双端队列,支持在两端进行插入和删除操作。
特点:
- 可以作为队列使用(FIFO)
- 可以作为栈使用(LIFO)
- 支持在两端操作
ArrayDeque
**ArrayDeque**是基于数组实现的双端队列。
特点:
- 性能好:比 LinkedList 性能更好
- 无容量限制:自动扩容
- 线程不安全:多线程环境下需要同步
- 不允许 null:不能存储 null 元素
import java.util.ArrayDeque;
import java.util.Deque;
Deque<String> deque = new ArrayDeque<>();
// 作为队列使用(FIFO)
deque.offerLast("first");
deque.offerLast("second");
String first = deque.pollFirst(); // "first"
// 作为栈使用(LIFO)
deque.push("first");
deque.push("second");
String top = deque.pop(); // "second"
常用操作方法(offer, poll, peek, push, pop)
Queue 方法
Queue<String> queue = new LinkedList<>();
// offer:添加元素到队尾
queue.offer("first");
queue.offer("second");
// poll:删除并返回队首元素
String head = queue.poll(); // "first"
// peek:查看队首元素(不删除)
String next = queue.peek(); // "second"
Deque 方法
队列操作(FIFO)
Deque<String> deque = new ArrayDeque<>();
// 队尾添加
deque.offerLast("first");
deque.offerLast("second");
// 队首删除
String first = deque.pollFirst(); // "first"
// 队首查看
String next = deque.peekFirst(); // "second"
栈操作(LIFO)
Deque<String> stack = new ArrayDeque<>();
// 入栈
stack.push("first");
stack.push("second");
// 出栈
String top = stack.pop(); // "second"
// 查看栈顶
String peek = stack.peek(); // "first"
双端操作
Deque<String> deque = new ArrayDeque<>();
// 在队首添加
deque.offerFirst("first");
deque.offerFirst("second");
// 在队尾添加
deque.offerLast("third");
// 从队首删除
String first = deque.pollFirst(); // "second"
// 从队尾删除
String last = deque.pollLast(); // "third"
// 查看队首
String head = deque.peekFirst(); // "first"
// 查看队尾
String tail = deque.peekLast(); // "first"
方法对比
| 操作 | Queue | Deque(队列) | Deque(栈) |
|---|---|---|---|
| 添加 | offer() | offerLast() | push() |
| 删除 | poll() | pollFirst() | pop() |
| 查看 | peek() | peekFirst() | peek() |
实际示例
示例 1:队列基本操作
import java.util.*;
public class QueueExample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
// 添加元素
queue.offer("任务1");
queue.offer("任务2");
queue.offer("任务3");
// 处理队列
while (!queue.isEmpty()) {
String task = queue.poll();
System.out.println("处理:" + task);
}
}
}