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 有更好的性能表现。

相关推荐
xmjd msup19 分钟前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
9523644 分钟前
SpringBoot统一功能处理
java·spring boot·后端
有一个好名字1 小时前
工具即双手 —— 从 Bash 到 Tool Dispatch Map
开发语言·chrome·bash
Lyyaoo.1 小时前
优惠券秒杀业务分析
java·开发语言
消失的旧时光-19431 小时前
统一并发模型:线程、Reactor、协程本质是一件事(从线程到协程 · 第6篇·终章)
java·python·算法
勿忘初心12211 小时前
Java 国密 SM4 加密工具类实战(Hutool + BouncyCastle)|企业级数据加密 + 兼容 JDK8
java·数据安全·数据加密·后端开发·企业级开发·国密 sm4
庞轩px1 小时前
第8篇:原子类与CAS底层原理——无锁并发的实现
java·cas·乐观锁·aba·无锁编程·自旋
rleS IONS1 小时前
SpringBoot中自定义Starter
java·spring boot·后端
DevilSeagull1 小时前
MySQL(2) 客户端工具和建库
开发语言·数据库·后端·mysql·服务
苍煜2 小时前
慢SQL优化实战教学
java·数据库·sql