245. Java 集合 - 使用 Deque 同时建模 LIFO 栈 和 FIFO 队列
在 Java SE 6 中,Deque 接口(Double Ended Queue,双端队列)被引入,作为 Queue 接口的扩展。 Deque 不仅保留了 Queue 的方法,还增加了一套更清晰、更有方向感的命名规则,并且支持双端操作,使得 Deque 既可以充当栈(LIFO)也可以充当队列(FIFO)。
📋 Deque 中 FIFO 相关的方法一览(队列行为)
| 操作 | 方法 | 队列已满或为空时的行为 |
|---|---|---|
| 插入元素(尾部) | addLast(element) | 如果队列已满,抛出 IllegalStateException |
| 插入元素(尾部) | offerLast(element) | 如果队列已满,返回 false |
| 移除元素(头部) | removeFirst() | 如果队列为空,抛出 NoSuchElementException |
| 移除元素(头部) | pollFirst() | 如果队列为空,返回 null |
| 查看元素(头部) | getFirst() | 如果队列为空,抛出 NoSuchElementException |
| 查看元素(头部) | peekFirst() | 如果队列为空,返回 null |
🔥 注意事项
- Deque 的 peek 操作用的是
getFirst()/getLast(),而在 Queue 中是element()。 - Deque 额外定义了栈操作的方法,比如:
push(element):将元素压入到队列的头部(= addFirst)pop():弹出并返回头部元素(= removeFirst)poll():弹出尾部元素(= removeLast)peek():查看尾部元素(= peekLast)
🛠️ 示例演示:Deque 作为栈(LIFO)
import java.util.ArrayDeque;
import java.util.Deque;
public class DequeAsStackExample {
public static void main(String[] args) {
Deque<String> stack = new ArrayDeque<>();
// 压入元素
stack.push("A");
stack.push("B");
stack.push("C");
System.out.println("Stack: " + stack); // [C, B, A]
// 查看栈顶元素
System.out.println("Peek: " + stack.peek()); // C
// 弹出元素
System.out.println("Pop: " + stack.pop()); // C
System.out.println("Stack after pop: " + stack); // [B, A]
}
}
输出结果:
mathematica复制编辑Stack: [C, B, A]
Peek: C
Pop: C
Stack after pop: [B, A]
🛠️ 示例演示:Deque 作为队列(FIFO)
import java.util.ArrayDeque;
import java.util.Deque;
public class DequeAsQueueExample {
public static void main(String[] args) {
Deque<String> queue = new ArrayDeque<>();
// 入队列
queue.offerLast("A");
queue.offerLast("B");
queue.offerLast("C");
System.out.println("Queue: " + queue); // [A, B, C]
// 查看队头元素
System.out.println("Peek First: " + queue.peekFirst()); // A
// 出队列
System.out.println("Poll First: " + queue.pollFirst()); // A
System.out.println("Queue after poll: " + queue); // [B, C]
}
}
输出结果:
Queue: [A, B, C]
Peek First: A
Poll First: A
Queue after poll: [B, C]
🎯 小结
| 使用方式 | 方法关键词 | 说明 |
|---|---|---|
| 栈(LIFO) | push / pop / peekFirst | 先进后出 |
| 队列(FIFO) | offerLast / pollFirst / peekFirst | 先进先出 |
- Deque 超灵活!
- 头插头取 👉 栈模式(LIFO)
- 尾插头取 👉 队列模式(FIFO)
- 安全优先:使用
offerFirst()/offerLast(),pollFirst()/pollLast(),peekFirst()/peekLast(),避免抛异常!
🧐 互动问题
问题:
如果用 ArrayDeque 作为栈,调用 pop() 时队列为空,会发生什么?
答案:
会抛出 NoSuchElementException!