Java中的ArrayDeque是基于数组实现的双端队列,它同时实现了Deque接口,既可以作为普通队列使用,也可以作为栈使用,在很多场景下比传统的LinkedList有更好的性能表现。

ArrayDeque的底层实现原理
ArrayDeque内部维护了一个动态扩容的数组,通过两个指针分别指向队列的头部和尾部,实现双端的高效操作。和LinkedList的链表节点存储不同,ArrayDeque的数组存储方式减少了节点对象的创建开销,内存利用率更高。
当数组容量不足时,ArrayDeque会自动进行扩容,扩容后的容量是原容量的两倍,这个机制保证了大部分操作的均摊时间复杂度为O(1)。
核心属性说明
ArrayDeque的核心属性如下:
// 存储元素的数组 transient Object[] elements; // 头部指针,指向队列第一个元素的位置 transient int head; // 尾部指针,指向队列最后一个元素的下一个位置 transient int tail;
ArrayDeque的核心优势
1. 内存占用更低
LinkedList作为链表实现的队列,每个元素都需要封装成一个节点对象,节点除了存储元素本身,还需要存储前驱和后继的引用,额外内存开销较大。而ArrayDeque基于数组存储,只需要一个数组对象,元素直接存储在数组中,没有额外的节点开销,内存利用率更高。
2. 操作性能更优
ArrayDeque的入队、出队、获取头部元素等核心操作都是基于数组的下标访问,时间复杂度为O(1),而且数组的连续存储特性对CPU缓存更友好,实际运行速度比LinkedList的链表遍历更快。下面是两种队列实现的操作性能对比:
| 操作类型 | ArrayDeque时间复杂度 | LinkedList时间复杂度 |
|---|---|---|
| 队尾入队 | O(1)(均摊) | O(1) |
| 队头出队 | O(1)(均摊) | O(1) |
| 获取队头元素 | O(1) | O(1) |
| 随机访问 | O(1) | O(n) |
3. 支持双端操作和栈功能
ArrayDeque实现了Deque接口,支持在队列两端进行元素的添加和删除,既可以当作先进先出的队列使用,也可以当作后进先出的栈使用。作为栈使用时,它的性能比传统的Stack类更好,官方也推荐优先使用ArrayDeque实现栈功能。
ArrayDeque的使用示例
作为普通队列使用
作为队列使用时,通常调用offer方法入队,poll方法出队,peek方法获取队头元素:
import java.util.ArrayDeque;
import java.util.Queue;
public class ArrayDequeQueueDemo {
public static void main(String[] args) {
Queue<String> queue = new ArrayDeque<>();
// 入队操作
queue.offer("元素1");
queue.offer("元素2");
queue.offer("元素3");
// 获取队头元素,不删除
System.out.println("队头元素:" + queue.peek());
// 出队操作
while (!queue.isEmpty()) {
System.out.println("出队元素:" + queue.poll());
}
}
}
作为栈使用
作为栈使用时,调用push方法入栈,pop方法出栈,peek方法获取栈顶元素:
import java.util.ArrayDeque;
import java.util.Deque;
public class ArrayDequeStackDemo {
public static void main(String[] args) {
Deque<String> stack = new ArrayDeque<>();
// 入栈操作
stack.push("元素A");
stack.push("元素B");
stack.push("元素C");
// 获取栈顶元素
System.out.println("栈顶元素:" + stack.peek());
// 出栈操作
while (!stack.isEmpty()) {
System.out.println("出栈元素:" + stack.pop());
}
}
}
ArrayDeque的使用限制
虽然ArrayDeque有很多优势,但它也有对应的使用限制:
- ArrayDeque不允许存储null元素,如果尝试添加null会抛出空指针异常,而LinkedList允许存储null。
- ArrayDeque不是线程安全的,如果在多线程环境下使用,需要额外加同步机制,或者使用
LinkedBlockingDeque等线程安全的队列实现。 - ArrayDeque的迭代器是快速失败的,如果在迭代过程中修改了队列结构,会抛出
ConcurrentModificationException异常。
适用场景总结
如果你的场景是单线程下的队列或者栈操作,不需要存储null元素,那么优先选择ArrayDeque,它能带来更好的性能和更低的内存占用。如果需要存储null元素,或者需要线程安全的队列实现,那么可以选择LinkedList或者对应的线程安全队列实现。
ArrayDequeJava队列双端队列数组实现修改时间:2026-06-10 08:12:22