java基础-Deque 接口

1. 什么是 Deque?

Deque(Double Ended Queue,双端队列)是 Java Collections Framework 的一部分,它支持在队列的两端进行插入和删除操作。

2. Deque 的特点

  • 双端操作:可以从头部和尾部添加/删除元素

  • 可用作多种数据结构

    • 普通队列(FIFO)

    • 栈(LIFO)

    • 双端队列

3. 主要实现类

java 复制代码
// ArrayDeque - 基于数组实现,性能较好,推荐使用
Deque<String> arrayDeque = new ArrayDeque<>();

// LinkedList - 基于链表实现,也实现了Deque接口
Deque<String> linkedListDeque = new LinkedList<>();

// ConcurrentLinkedDeque - 线程安全版本(java.util.concurrent)
Deque<String> concurrentDeque = new ConcurrentLinkedDeque<>();

4. 常用操作方法

4.1 添加元素

java 复制代码
Deque<Integer> deque = new ArrayDeque<>();

// 头部操作
deque.addFirst(1);      // 抛出异常
deque.offerFirst(2);    // 返回boolean

// 尾部操作
deque.addLast(3);       // 抛出异常
deque.offerLast(4);     // 返回boolean

// 等价方法
deque.add(5);           // addLast()
deque.offer(6);         // offerLast()
deque.push(7);          // addFirst() - 栈操作

4.2 删除元素

java 复制代码
// 头部删除
int first1 = deque.removeFirst();  // 抛出异常
int first2 = deque.pollFirst();    // 返回null

// 尾部删除
int last1 = deque.removeLast();    // 抛出异常
int last2 = deque.pollLast();      // 返回null

// 等价方法
int elem1 = deque.remove();        // removeFirst()
int elem2 = deque.poll();          // pollFirst()
int elem3 = deque.pop();           // removeFirst() - 栈操作

4.3 查看元素(不删除)

java 复制代码
// 查看头部
int head1 = deque.getFirst();      // 抛出异常
int head2 = deque.peekFirst();     // 返回null
int head3 = deque.element();       // getFirst()
int head4 = deque.peek();          // peekFirst()

// 查看尾部
int tail1 = deque.getLast();       // 抛出异常
int tail2 = deque.peekLast();      // 返回null

5. 使用示例

示例1:作为栈使用

java 复制代码
Deque<Integer> stack = new ArrayDeque<>();

// 入栈
stack.push(1);
stack.push(2);
stack.push(3);

// 出栈
while (!stack.isEmpty()) {
    System.out.println(stack.pop());  // 输出: 3, 2, 1
}

示例2:作为队列使用

java 复制代码
Deque<String> queue = new ArrayDeque<>();

// 入队
queue.offer("A");
queue.offer("B");
queue.offer("C");

// 出队
while (!queue.isEmpty()) {
    System.out.println(queue.poll());  // 输出: A, B, C
}

示例3:双端操作

java 复制代码
Deque<Character> deque = new ArrayDeque<>();

// 两端添加
deque.addFirst('B');
deque.addLast('C');
deque.addFirst('A');
deque.addLast('D');

// 遍历
for (char c : deque) {
    System.out.print(c + " ");  // 输出: A B C D
}

// 两端删除
System.out.println(deque.removeFirst());  // A
System.out.println(deque.removeLast());   // D

6. ArrayDeque vs LinkedList

特性 ArrayDeque LinkedList
数据结构 可扩展数组 双向链表
内存使用 更紧凑 每个元素额外存储前后指针
性能 随机访问快 插入删除快(指定位置)
推荐使用 大多数场景 需要频繁在中间操作时

7. 实际应用场景

java 复制代码
// 场景1:滑动窗口最大值
public int[] maxSlidingWindow(int[] nums, int k) {
    Deque<Integer> deque = new ArrayDeque<>();
    int[] result = new int[nums.length - k + 1];
    
    for (int i = 0; i < nums.length; i++) {
        // 移除超出窗口的元素
        if (!deque.isEmpty() && deque.peekFirst() == i - k) {
            deque.pollFirst();
        }
        
        // 保持deque递减
        while (!deque.isEmpty() && nums[deque.peekLast()] <= nums[i]) {
            deque.pollLast();
        }
        
        deque.offerLast(i);
        
        // 记录窗口最大值
        if (i >= k - 1) {
            result[i - k + 1] = nums[deque.peekFirst()];
        }
    }
    return result;
}

// 场景2:括号匹配检查
public boolean isValid(String s) {
    Deque<Character> stack = new ArrayDeque<>();
    
    for (char c : s.toCharArray()) {
        if (c == '(' || c == '[' || c == '{') {
            stack.push(c);
        } else {
            if (stack.isEmpty()) return false;
            char top = stack.pop();
            if ((c == ')' && top != '(') ||
                (c == ']' && top != '[') ||
                (c == '}' && top != '{')) {
                return false;
            }
        }
    }
    return stack.isEmpty();
}

8. 注意事项

  1. 容量限制:ArrayDeque 有初始容量,可自动扩容

  2. 空值处理

    • addFirst/addLast:不接受 null(会抛出 NPE)

    • offerFirst/offerLast:不接受 null

  3. 线程安全:ArrayDeque 和 LinkedList 都不是线程安全的

  4. 性能考虑:ArrayDeque 通常比 LinkedList 性能更好

总结

Deque 是一个非常实用的接口,它提供了队列和栈的完整功能。在大多数情况下,推荐使用 ArrayDeque 作为实现类,因为它比 LinkedList 有更好的性能表现。

相关推荐
l1t3 分钟前
duckdb 1.6dev新增的.manual命令
开发语言·数据库
你怎么知道我是队长9 分钟前
JavaScript的函数介绍
开发语言·前端·javascript
YMWM_15 分钟前
python-venv虚拟环境
linux·开发语言·python
折哥的程序人生 · 物流技术专研23 分钟前
Java 23 种设计模式:从踩坑到精通 | 备忘录模式 —— 快照与撤销,给对象装一个“后悔药”
java·设计模式·备忘录模式·行为型模式·java设计模式·从踩坑到精通·撤销重做
ikun_文29 分钟前
Java里面异常Exception体系知识点
java
不负岁月无痕31 分钟前
STL -- C++ 红黑树封装 Map 和 Set
java·c语言·开发语言·c++·面试
小园子的小菜35 分钟前
Java核心基础:反射与泛型底层原理及实战用法详解
java·开发语言
淘源码A42 分钟前
多院区集团化云PACS系统源码,原生兼容国产软硬件环境
java·云计算·源码·saas·pacs·医学影像系统
何中应1 小时前
主流 OpenJDK 发行版下载安装
java·oracle·jdk·openjdk
daad7771 小时前
记录vscode连接matlab启动环境搭建
java·vscode·matlab