arraydeque是java中推荐替代stack和linkedlist的高效双端队列,基于循环数组实现,支持o(1)头尾操作、无同步开销、内存连续缓存友好,且非线程安全;作为栈用push/pop/peek(头端操作),作为队列用offer/poll/peek(尾进头出),性能优于stack(同步冗余)和linkedlist(gc压力大、缓存不友好)。

ArrayDeque 是 Java 中推荐用来替代 Stack 和传统 Queue 实现的高效双端队列类,它底层基于循环数组,支持 O(1) 的头尾增删操作,且线程不安全但性能远优于 Stack(继承自 Vector,同步开销大)和 LinkedList(链表节点开销高)。
用 ArrayDeque 当栈(LIFO)
Stack 类已过时,不推荐继承或使用。ArrayDeque 提供 push()、pop()、peek() 方法,语义与栈完全一致,且更快更省内存。
- 用
push(e)替代Stack.push(e)—— 从队首添加元素 - 用
pop()替代Stack.pop()—— 从队首移除并返回元素,空时抛NoSuchElementException - 用
peek()替代Stack.peek()—— 查看队首元素,不移除 - 避免用
add()或offer()做栈操作,它们默认加到队尾,会破坏 LIFO 语义
用 ArrayDeque 当队列(FIFO)
ArrayDeque 实现了 Queue 接口,是 LinkedList 的高性能替代品,尤其适合高频入队/出队场景。
- 入队:用
offer(e)或add(e)(后者失败时抛异常)→ 元素加到队尾 - 出队:用
poll()(空时返回null)或remove()(空时抛异常)→ 移除并返回队首元素 - 查看队首:用
peek()(空时返回null)或element()(空时抛异常) - 注意不要混用栈和队列方法(如 push + poll),逻辑易错;明确用途后统一用对应 API
为什么比 Stack 和 LinkedList 更好
Stack 继承自 Vector,所有方法都 synchronized,单线程下纯属冗余开销;LinkedList 是双向链表,每次操作都要新建 Node 对象,GC 压力大,缓存局部性差。
- ArrayDeque 底层是动态扩容的 Object 数组,内存连续,CPU 缓存友好
- 增删都在头/尾,无需遍历,均摊时间复杂度 O(1)
- 初始容量为 16,扩容策略是翻倍(非严格 2 的幂,但保证快速索引计算)
- 无同步、无包装对象,轻量干净,JDK 自身大量内部实现(如 Collections.sort 的临时栈)也优先选用它
实际使用小建议
声明类型优先用接口,增强灵活性;初始化时可预估大小减少扩容次数。
- 栈场景:声明为
Deque<integer> stack = new ArrayDeque();</integer> - 队列场景:声明为
Queue<string> queue = new ArrayDeque();</string> - 若确定容量上限,可用构造函数
new ArrayDeque(initialCapacity)避免多次扩容 - 不要用
size() == 0判空,改用isEmpty(),语义更清晰且部分实现可能有优化
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











