Java泛型Queue实现:如何基于自定义Stack类完成队列功能?
用双栈实现泛型队列的完整方案
这是个经典的用双栈模拟队列的问题,我来一步步帮你理清思路并补全代码~
核心思路
队列遵循先进先出(FIFO),而栈是后进先出(LIFO),我们可以用两个栈配合来反转元素顺序:
- 一个栈(
next)专门负责接收新入队的元素(入栈方向) - 另一个栈(
next2)专门负责提供出队/取队首的元素(出栈方向) - 当
next2为空时,把next里的所有元素逐个弹出压入next2,这样next的栈底元素就变成了next2的栈顶,完美匹配队列的FIFO顺序。
完整代码实现
首先建议先在构造函数里初始化两个栈,避免空指针问题,然后逐个补全方法:
import java.util.NoSuchElementException; public class Queue<E> { private Stack<E> next; // 负责入队的栈 private Stack<E> next2; // 负责出队的栈 // 构造函数初始化栈 public Queue() { next = new Stack<>(); next2 = new Stack<>(); } // 获取队首元素 public E first() { if (isEmpty()) { throw new NoSuchElementException("Queue is empty, cannot get first element"); } // 如果出队栈为空,将入队栈的元素全部转移过去 if (next2.isEmpty()) { transferElements(); } return next2.peek(); } // 入队操作:直接压入入队栈 public Queue<E> enqueue(E e) { next.push(e); return this; } // 出队操作:弹出出队栈的栈顶元素 public Queue<E> dequeue() { if (isEmpty()) { throw new NoSuchElementException("Queue is empty, cannot dequeue"); } if (next2.isEmpty()) { transferElements(); } next2.pop(); return this; } // 判断队列是否为空:两个栈都为空才是队列空 public boolean isEmpty() { return next.isEmpty() && next2.isEmpty(); } // 辅助方法:将next的元素转移到next2 private void transferElements() { while (!next.isEmpty()) { next2.push(next.pop()); } } }
关于你提到的reverse方法
如果你的Stack类提供了reverse方法,确实可以用它来替代transferElements里的while循环,比如:
private void transferElements() { next2 = next.reverse(); // 假设reverse返回一个反转后的新栈 next.clear(); }
但要注意:
- 确认
reverse方法的行为:是修改原栈还是返回新栈? - 用while循环逐个弹压的方式更通用,不依赖
Stack类的额外方法,逻辑也更直观,适合理解双栈实现队列的核心逻辑。
关键注意点
- 必须同时判断两个栈是否为空才能确定队列是否为空,不能只检查其中一个
- 转移元素的操作只在
next2为空时才进行,避免重复转移影响效率(均摊时间复杂度为O(1)) - 空队列操作要抛出异常(或者根据需求返回null,抛出异常更符合Java集合的规范)
内容的提问来源于stack exchange,提问作者eliasmartin
相关产品推荐
相关产品推荐

