Java中双端队列的多种实现类详解
双端队列(Deque,即Double Ended Queue)是Java集合框架中的重要组成部分,它允许在队列的两端高效地插入和删除元素。本文我将深入剖析Java中四种主要的双端队列实现类:ArrayDeque、LinkedList、ConcurrentLinkedDeque和LinkedBlockingDeque,通过源码分析和性能对比,帮你掌握在不同应用场景下双端队列的最优选择。
一、双端队列概述与核心接口
双端队列(Deque)是一种特殊的队列,支持在队列的头部和尾部进行高效的插入和删除操作。在Java中,Deque接口继承自Queue接口,定义了一套标准的双端操作方法:
public interface Deque<E> extends Queue<E> {
// 头部操作
void addFirst(E e);
boolean offerFirst(E e);
E removeFirst();
E pollFirst();
E getFirst();
E peekFirst();
// 尾部操作
void addLast(E e);
boolean offerLast(E e);
E removeLast();
E pollLast();
E getLast();
E peekLast();
// 栈操作
void push(E e);
E pop();
// 迭代器
Iterator<E> descendingIterator();
}
Deque接口提供了两套操作方法:一套在操作失败时抛出异常(如addFirst()),另一套返回特殊值(如offerFirst()返回false)。这种设计模式为不同使用场景提供了灵活性。
二、ArrayDeque:基于动态数组的双端队列实现
核心特性
- 底层结构:循环数组,数组长度始终为2的幂
- 扩容机制:容量不足时自动扩容为原容量的2倍
- 性能特点:随机访问时间复杂度O(1),插入删除平均O(1)
- 限制条件:不允许存储
null元素
源码分析:循环数组的奥秘
ArrayDeque使用两个索引变量head和tail来标记队列的头部和尾部:
transient Object[] elements; // 存储元素的数组
transient int head; // 头部元素索引
transient int tail; // 尾部元素的下一个位置索引
插入元素时的索引计算采用位运算,确保在数组范围内循环:
// 添加到尾部
public void addLast(E e) {
if (e == null)
throw new NullPointerException();
elements[tail] = e;
// 位运算等价于 (tail + 1) % elements.length
if ((tail = (tail + 1) & (elements.length - 1)) == head)
doubleCapacity(); // 扩容
}
常用方法示例
Deque<String> deque = new ArrayDeque<>();
// 添加元素
deque.addFirst("A"); // 头部插入
deque.offerLast("B"); // 尾部插入
// 访问元素
String first = deque.peekFirst()

最低0.47元/天 解锁文章
1554

被折叠的 条评论
为什么被折叠?



