arraylist可模拟栈和队列,但仅推荐小规模使用;栈操作(push/pop/peek)在末尾为o(1),队列操作(offer/poll)因remove(0)为o(n)而低效;生产环境应优先选用arraydeque。

Java 的 ArrayList 本身不是为队列(FIFO)或栈(LIFO)设计的,但它可以通过限制操作方式,模拟这两种结构的行为。关键在于只使用特定位置的增删方法,避免破坏时间复杂度或逻辑一致性。
用 ArrayList 模拟栈(LIFO)
栈的核心是“后进先出”,所有操作集中在末尾(索引 size()-1)。ArrayList 的 add(E) 和 remove(int index) 在末尾操作是 O(1) 均摊复杂度,完全适用。
-
入栈(push):调用
list.add(element)—— 自动添加到末尾 -
出栈(pop):先检查非空,再调用
list.remove(list.size() - 1) -
查看栈顶(peek):取
list.get(list.size() - 1),不删除
示例:
Liststack.add("A"); // push
stack.add("B"); // push
String top = stack.get(stack.size() - 1); // peek → "B"
String popped = stack.remove(stack.size() - 1); // pop → "B"
用 ArrayList 模拟队列(FIFO)
队列要求“先进先出”,即从头(索引 0)出、从尾(索引 size-1)入。但 ArrayList 在头部删除(remove(0))是 O(n) 操作,因为后续元素要整体前移。所以仅适合小规模或对性能不敏感场景。
-
入队(offer/enqueue):用
list.add(element)(O(1)) -
出队(poll/dequeue):用
list.remove(0)(O(n),慎用) -
查看队首(peek):用
list.get(0)(O(1))
如果需要高效队列,应优先选用 ArrayDeque(底层循环数组,头尾操作均为 O(1)),它比 ArrayList 更合适,也比 LinkedList 更省内存。
为什么不直接用 ArrayList 做生产级队列/栈?
虽然语法上可行,但有明显短板:
- 用作队列时,频繁
remove(0)会引发大量数组复制,性能差 - 没有内置的线程安全机制,多线程下需额外同步
- 缺少语义化方法名(如
push/pop或offer/poll),可读性和维护性弱 - 标准库已有更优替代:
ArrayDeque可同时高效支持栈和队列操作
推荐做法:用 ArrayDeque 替代
ArrayDeque 是专为双端队列设计的类,内部用循环数组实现,头尾插入/删除都是 O(1),且实现了 Deque 接口,提供清晰的栈和队列方法:
-
当栈用:用
push(),pop(),peek() -
当队列用:用
offer(),poll(),peek()(或addFirst()/removeLast()等双端操作) - 无需手动管理索引,无扩容抖动,内存连续,缓存友好
一句话总结:ArrayList 可以“凑合”模拟,但真正要用,选 ArrayDeque 更自然、更高效、更安全。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











