Java Deque(双端队列)介绍与使用

Java Deque(双端队列)的使用指南

双端队列(Deque,全名为"Double Ended Queue")是Java集合框架中的一种数据结构,它允许在队列两端进行元素的插入和删除操作。Deque可以看作是既支持队列操作,又支持栈操作的一种数据结构,因为它同时具有FIFO(First-In-First-Out)和LIFO(Last-In-First-Out)的特性。在Java中,Deque接口位于java.util包中,它的实现类有ArrayDequeLinkedList

Deque接口的方法

Deque接口继承自Queue接口,因此它包含了Queue的所有方法,并在此基础上添加了一些特有的方法。下面是一些常用的Deque接口方法:

  • void addFirst(E e):在队列的头部插入元素。
  • void addLast(E e):在队列的尾部插入元素。
  • boolean offerFirst(E e):尝试在队列头部插入元素,如果成功返回true,否则返回false。
  • boolean offerLast(E e):尝试在队列尾部插入元素,如果成功返回true,否则返回false。
  • E removeFirst():移除并返回队列头部的元素,如果队列为空,则抛出异常。
  • E removeLast():移除并返回队列尾部的元素,如果队列为空,则抛出异常。
  • E pollFirst():移除并返回队列头部的元素,如果队列为空,则返回null。
  • E pollLast():移除并返回队列尾部的元素,如果队列为空,则返回null。
  • E getFirst():返回队列头部的元素,但不移除,如果队列为空,则抛出异常。
  • E getLast():返回队列尾部的元素,但不移除,如果队列为空,则抛出异常。
  • E peekFirst():返回队列头部的元素,但不移除,如果队列为空,则返回null。
  • E peekLast():返回队列尾部的元素,但不移除,如果队列为空,则返回null。

Deque的实现类

ArrayDeque

ArrayDeque是基于数组实现的双端队列,它不支持null元素,并且容量可以动态扩展。由于基于数组实现,它在随机访问和插入/删除操作上的性能都比较好。下面是一个使用ArrayDeque实现的窗口滑动最大值问题的示例:

import java.util.*;

public class ArrayDequeExample {
    public static void main(String[] args) {
        int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
        int k = 3;

        Deque<Integer> deque = new ArrayDeque<>();
        int[] result = new int[nums.length - k + 1];

        for (int i = 0; i < nums.length; i++) {
            while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
                deque.removeFirst(); // 移除超出窗口范围的元素
            }
            while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
                deque.removeLast(); // 保持队列中元素递减
            }
            deque.addLast(i); // 将当前元素加入队列尾部

            if (i >= k - 1) {
                result[i - k + 1] = nums[deque.peekFirst()]; // 窗口内的最大值
            }
        }

        System.out.println(Arrays.toString(result)); // 输出结果
    }
}

LinkedList

LinkedList同样实现了Deque接口,基于双向链表实现,支持null元素。由于是链表实现,LinkedList在插入/删除操作上相对快速,但随机访问的性能较差。下面是一个使用LinkedList实现的Undo/Redo功能的示例:

import java.util.*;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> history = new LinkedList<>();
        String currentText = "";

        // 模拟编辑操作
        history.add(currentText);
        currentText = "Hello";
        history.add(currentText);
        currentText = "Hello, World!";
        history.add(currentText);

        // 撤销操作
        currentText = history.removeLast(); // 恢复到"Hello"状态

        // 重做操作
        currentText = history.removeLast(); // 恢复到初始状态
    }
}

Deque的应用场景

双端队列在许多场景下都非常有用,例如:

  1. 任务调度: 可以将任务按照优先级插入队列的头部或尾部,实现任务的优先级调度。
  2. 窗口滑动: 在滑动窗口算法中,双端队列可以用来维护窗口内的最大/最小值。
  3. Undo/Redo功能: 在应用程序中实现撤销和重做功能时,可以使用双端队列来管理操作历史。
  4. 实现线程安全队列: 在多线程环境下,使用ConcurrentLinkedDeque实现线程安全的双端队列。

总结

双端队列(Deque)是Java集合框架中一个功能强大的数据结构,它支持在队列两端进行插入和删除操作,具备队列和栈的特性。通过ArrayDeque和LinkedList这两个实现类,可以根据实际需求选择合适的双端队列来解决问题。在编写代码时,根据具体场景选择不同的Deque实现,可以提高代码的效率和可读性。

希望这篇文章对你理解和使用Java中的双端队列有所帮助!

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贪吃的小松鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值