deque接口天然支持双端队列和栈两种角色:双端队列用addfirst/last等方法实现头尾操作,栈则用push/pop/peek统一操作尾端,arraydeque是推荐实现类。

Java 中的 Deque(Double Ended Queue)接口天然支持双端操作,既能当双端队列用,也能当栈用——关键在于选择哪一端插入/移除元素,而不是换类或写额外逻辑。
用 Deque 实现双端队列
Deque 本身是接口,常用实现类有 ArrayDeque(推荐,性能好、非线程安全)和 LinkedList(功能全但稍慢)。双端队列的核心能力是:头尾均可添加、删除元素。
-
从队首操作:用
addFirst(e)/offerFirst(e)插入;removeFirst()/pollFirst()移除(带Exception和null安全两种版本) -
从队尾操作:用
addLast(e)/offerLast(e)插入;removeLast()/pollLast()移除 - 例如:
Deque<integer> dq = new ArrayDeque(); dq.addFirst(1); dq.addLast(2);</integer>→ 队列为 [1, 2];再调dq.removeLast()得到 2,剩下 [1]
用 Deque 实现栈(LIFO)
栈只需保证“后进先出”,Deque 的尾端(last)操作完全满足:统一用 push()、pop()、peek() 即可。这三个方法本质是 addLast()、removeLast()、getFirst() 的别名,语义更清晰。
-
push(e)等价于addLast(e)(栈顶入) -
pop()等价于removeLast()(栈顶出,空时抛NoSuchElementException) -
peek()等价于peekLast()(只看栈顶不移除) - 注意:
Stack类已过时,官方明确建议用Deque替代
实际使用建议与注意事项
选对方法名比选实现类更重要:语义清晰才能降低出错概率。
- 优先用
ArrayDeque:它底层是循环数组,比LinkedList更省内存、缓存友好,且所有操作都是 O(1) 均摊 - 避免混用两端操作:比如用
push()入栈,却用removeFirst()出——这会破坏 LIFO,变成奇怪的混合行为 - 判空统一用
isEmpty();不要依赖size() == 0,虽等效但可读性差 - 如果需要线程安全,可用
ConcurrentLinkedDeque,但注意它不支持Iterator.remove()等部分操作
一个对比示例:队列 vs 栈行为
同一 ArrayDeque 实例,仅靠方法选择就切换角色:
-
当队列:用
offer(1)→offer(2)→poll()返回 1(FIFO) -
当栈:用
push(1)→push(2)→pop()返回 2(LIFO) - 两者底层都是同一个数据结构,只是 API 视角不同
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











