245. Java 集合 - 使用 Deque 同时建模 LIFO 栈 和 FIFO 队列

28 阅读2分钟

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