Java 集合深入理解(10):Deque 双端队列

本文详细介绍了Deque(双端队列)的概念及其在Java集合框架中的应用。Deque支持从两端进行插入、删除和检索操作,并提供了多种实现方式,如LinkedList和ArrayDeque。此外,文章还探讨了Deque在并发编程中的作用,特别是“工作密取”模式,以及其与传统生产者-消费者模式的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~


什么是 Deque

这里写图片描述

DequeDouble ended queue (双端队列) 的缩写,读音和 deck 一样,蛋壳。
Deque 继承自 Queue,直接实现了它的有 LinkedList, ArayDeque, ConcurrentLinkedDeque 等。
Deque 支持容量受限的双端队列,也支持大小不固定的。一般双端队列大小不确定。
Deque 接口定义了一些从头部和尾部访问元素的方法。比如分别在头部、尾部进行插入、删除、获取元素。和 Queue

类似,每个操作都有两种方法,一种在异常情况下直接抛出异常奔溃,另一种则不会抛异常,而是返回特殊的值,比如 false, null …

这里写图片描述

插入(Insert)方法的第二种是针对固定大小的双端队列设计的。大多数情况下 插入都不会失败。

Deque 继承了 Queue 接口的方法。当 Deque 当做 队列使用时(FIFO),添加元素是添加到队尾,删除时删除的是头部元素。从 Queue 接口继承的方法对应容器的方法如图所示:

这里写图片描述

Deque 也能当栈用(后进先出)。这时入栈、出栈元素都是在 双端队列的头部 进行。Deque 中和栈对应的方法如图所示:

这里写图片描述

Deque 包含的方法如下图所示:

这里写图片描述

根据名字就能看到功能,具体实现我们下篇看 LinkedList 源码时介绍。

Deque 的实现类

Deque 的实现类主要分为两种场景:

  • 一般场景
    • LinkedList 大小可变的链表双端队列,允许元素为 null
    • ArrayDeque 大下可变的数组双端队列,不允许 null
  • 并发场景
    • LinkedBlockingDeque 如果队列为空时,获取操作将会阻塞,知道有元素添加

Deque 与 工作密取

在并发编程 中,双端队列 Deque 还用于 “工作密取” 模式。

什么是工作密取呢?

在 生产者-消费者 模式中,所有消费者都从一个工作队列中取元素,一般使用阻塞队列实现;
而在 工作密取 模式中,每个消费者有其单独的工作队列,如果它完成了自己双端队列中的全部工作,那么它就可以从其他消费者的双端队列末尾秘密地获取工作。
工作密取 模式 对比传统的 生产者-消费者 模式,更为灵活,因为多个线程不会因为在同一个工作队列中抢占内容发生竞争。在大多数时候,它们只是访问自己的双端队列。即使需要访问另一个队列时,也是从 队列的尾部获取工作,降低了队列上的竞争程度。

Thanks

https://docs.oracle.com/javase/tutorial/collections/interfaces/deque.html
https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html
http://www.nowamagic.net/librarys/veda/detail/2296
《Java 并发编程实战》

### JavaDeque 接口的使用方法和实例 #### 使用场景与特性 Deque双端队列(Double-ended Queue) 的缩写,在Java集合框架中由`java.util.Deque`接口表示。该接口支持在两端进行插入和移除操作,提供了线程安全的选择,并且可以作为栈或者队列来使用[^1]。 #### 创建并初始化 Deque 对象 为了创建一个 `Deque` 实现的对象,通常会选择具体的实现如 `ArrayDeque` 或者 `LinkedList` 来完成这一过程。下面是一个基于 `LinkedList` 构建 `Deque` 并向其中添加元素的例子: ```java // Java Program Demonstrate addFirst() method of Deque import java.util.*; public class Example { public static void main(String[] args) throws IllegalStateException { // Create object of Deque using LinkedList implementation Deque<Integer> deque = new LinkedList<>(); // Add elements to both ends of the deque deque.addFirst(7855642); deque.addFirst(35658786); deque.addLast(5278367); deque.addLast(74381793); // Print out contents of deque System.out.println("Deque content: " + deque); } } ``` 这段代码展示了如何利用 `addFirst()` 和 `addLast()` 方法分别往双端队列头部和尾部增加新项[^2]。 #### 遍历 Deque 结构中的数据 遍历 `Deque` 可以通过增强型for循环(`foreach`)轻松达成,这种方式不仅简洁而且效率高。对于任何型的列表来说都是适用的。这里给出一段简单的例子用于演示如何迭代访问 `Deque` 内存的数据条目: ```java // Initialize an ArrayDeque with some strings. ArrayDeque<String> stringDeque = new ArrayDeque<>(); stringDeque.offer("One"); stringDeque.offer("Two"); stringDeque.offer("Three"); // Iterate over each element within the deque structure. for (String item : stringDeque) { System.out.println(item); } ``` 上述片段说明了怎样运用 `foreach` 循环语句配合 `offer()` 函数填充容器之后再逐一遍历输出各个成员[^3]。 #### 常见的操作函数总结表 | 操作 | 描述 | | --- | --- | | offer(e)/push(e)| 将指定元素插入此deque所代表的一端(取决于具体调用的方法),如果无法这样做,则返回false| | poll()/pop() | 获取并删除最前面/最近被压入堆栈的那个元素;如果没有可用元素则返回null或抛出异常| | peek() | 查看但不移除此deque的第一个元素|
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

拭心

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

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

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

打赏作者

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

抵扣说明:

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

余额充值