Java Deque 和 ArrayDeque(栈的推荐使用) 基本介绍以及使用
·
Deque 接口和 ArrayDeque 概述
Deque(双端队列)接口是 Java 集合框架中的一个重要接口,代表可以在两端进行插入和删除操作的队列。ArrayDeque 是 Deque 接口的一个高效实现类。
ArrayDeque 的主要特点
- 双端操作: 支持在队列两端进行插入和删除操作
- 无容量限制: 可以动态扩容
- 非线程安全: 不是线程安全的,多线程环境下需要外部同步
- 高性能: 比
Stack和LinkedList实现栈和队列更高效
ArrayDeque 的主要方法
栈操作方法(LIFO)
push(E e): 将元素压入双端队列的头部pop(): 弹出双端队列头部的元素peek(): 获取但不移除双端队列头部的元素
队列操作方法(FIFO)
addFirst(E e): 在双端队列头部添加元素addLast(E e): 在双端队列尾部添加元素removeFirst(): 移除并返回双端队列头部元素removeLast(): 移除并返回双端队列尾部元素getFirst(): 获取但不移除双端队列头部元素getLast(): 获取但不移除双端队列尾部元素
通用操作方法
offerFirst(E e): 在双端队列头部插入元素,成功返回 trueofferLast(E e): 在双端队列尾部插入元素,成功返回 truepollFirst(): 获取并移除双端队列头部元素,队列为空时返回 nullpollLast(): 获取并移除双端队列尾部元素,队列为空时返回 nullpeekFirst(): 获取但不移除双端队列头部元素,队列为空时返回 nullpeekLast(): 获取但不移除双端队列尾部元素,队列为空时返回 null- [size()](file://D:\zeekr-dict-server\zeekr-dict-server-infrastructure\src\main\java\com\zeekr\bigdata\dict\infrastructure\integration\redis\RedisTemplateService.java#L308-L308): 返回双端队列中元素的数量
isEmpty(): 判断双端队列是否为空
ArrayDeque 使用示例
作为栈使用
Deque<Integer> stack = new ArrayDeque<>();
// 压入元素
stack.push(10);
stack.push(20);
stack.push(30);
// 查看栈顶元素
Integer top = stack.peek(); // 返回 30
// 弹出元素
Integer popped = stack.pop(); // 返回并移除 30
// 检查是否为空
boolean isEmpty = stack.isEmpty(); // 返回 false
作为队列使用
Deque<String> queue = new ArrayDeque<>();
// 入队
queue.offerLast("first");
queue.offerLast("second");
queue.offerLast("third");
// 查看队首元素
String first = queue.peekFirst(); // 返回 "first"
// 出队
String removed = queue.pollFirst(); // 返回并移除 "first"
双端操作示例
Deque<Character> deque = new ArrayDeque<>();
// 在两端添加元素
deque.offerFirst('A');
deque.offerLast('Z');
deque.offerFirst('B');
deque.offerLast('Y');
// deque 现在是: B, A, Z, Y
// 从两端移除元素
Character firstChar = deque.pollFirst(); // 返回 'B'
Character lastChar = deque.pollLast(); // 返回 'Y'
使用场景
1. 实现高效的栈结构
public class EfficientStack<E> {
private Deque<E> deque = new ArrayDeque<>();
public void push(E item) {
deque.push(item);
}
public E pop() {
return deque.pop();
}
public E peek() {
return deque.peek();
}
public boolean isEmpty() {
return deque.isEmpty();
}
}
2. 实现队列结构
public class EfficientQueue<E> {
private Deque<E> deque = new ArrayDeque<>();
public void enqueue(E item) {
deque.offerLast(item);
}
public E dequeue() {
return deque.pollFirst();
}
public E front() {
return deque.peekFirst();
}
public boolean isEmpty() {
return deque.isEmpty();
}
}
3. 滑动窗口最大值问题
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums.length == 0 || k == 0) return new int[0];
Deque<Integer> deque = new ArrayDeque<>();
int[] result = new int[nums.length - k + 1];
int index = 0;
for (int i = 0; i < nums.length; i++) {
// 移除超出窗口范围的索引
while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
deque.pollFirst();
}
// 移除所有小于当前元素的索引
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
deque.offerLast(i);
// 当窗口形成后开始记录最大值
if (i >= k - 1) {
result[index++] = nums[deque.peekFirst()];
}
}
return result;
}
4. 回文检查
public boolean isPalindrome(String str) {
Deque<Character> deque = new ArrayDeque<>();
// 将字符添加到双端队列中
for (char c : str.toCharArray()) {
deque.offerLast(c);
}
// 从两端比较字符
while (deque.size() > 1) {
if (!deque.pollFirst().equals(deque.pollLast())) {
return false;
}
}
return true;
}
优势对比
ArrayDeque vs Stack
ArrayDeque性能更好,Stack继承自Vector有不必要的同步开销ArrayDeque不会抛出EmptyStackException,而是返回nullArrayDeque是Deque接口的推荐实现
ArrayDeque vs LinkedList
ArrayDeque在大多数操作上比LinkedList更快ArrayDeque内存使用更紧凑LinkedList允许 null 元素,而ArrayDeque不允许
注意事项
ArrayDeque不允许存储null元素- 不是线程安全的,在多线程环境中需要外部同步
- 迭代器是快速失败的(fail-fast)
- 当用作栈时,
ArrayDeque比传统的Stack类更推荐使用
以上部分内容由大模型生成,注意识别!
更多推荐
所有评论(0)