Java并发基础:Deque接口和Queue接口的区别?

Java并发基础:Deque接口和Queue接口的区别? - 程序员古德

核心概念

Deque(double ended queue,双端队列)和Queue(队列)都是Java集合框架中的接口,它们用于处理元素的排队和出队,但是它们之间存在一些重要的区别,如下:

1、Queue接口

Queue接口代表一个先进先出(FIFO)的队列,只能从一端添加元素,并从另一端移除元素,因此,可以使用add()offer()方法将元素添加到队列的末尾,使用remove()poll()方法从队列的头部移除元素,如果尝试从一个空的队列中移除元素,remove()方法会抛出NoSuchElementException,而poll()方法则会返回null

2、Deque接口

Deque接口,即双端队列,允许从两端添加或者移除元素,它提供了两套添加和移除元素的方法,一套在队列的头部操作,另一套在队列的尾部操作,因此Deque就可以当作队列(FIFO)或者栈(LIFO)来使用,对于Deque,可以在队列头部使用addFirst()offerFirst()添加元素,使用removeFirst()pollFirst()移除元素;在队列尾部使用addLast()offerLast()添加元素,使用removeLast()pollLast()移除元素,如果尝试从一个空的双端队列中移除元素,那么相关的removeXXX()方法同样会抛出NoSuchElementException,而pollXXX()方法会返回null

Queue接口和Deque接口的主要区别在于,Queue接口仅支持在一端添加元素,在另一端移除元素,而Deque接口则支持在两端都进行添加和移除元素的操作,另外,Deque接口的功能更强大,因为它可以当作队列、栈或者双端队列来使用,而Queue接口只能当作队列来使用。

代码案例

Java并发基础:Deque接口和Queue接口的区别? - 程序员古德

Deque

Deque接口代表一个双端队列(double-ended queue),双端队列是一个具有队列和栈的性质的数据结构,它允许元素从两端插入和删除,因此可以在队列的前面(头部)或后面(尾部)添加或移除元素,它的主要功能包括:

1、添加元素:

  1. addFirst(E e) / offerFirst(E e):在队列的头部插入元素,如果队列已满,addFirst会抛出IllegalStateException,而offerFirst则返回false
  2. addLast(E e) / offerLast(E e):在队列的尾部插入元素,如果队列已满,addLast会抛出IllegalStateException,而offerLast则返回false

2、移除元素:

  1. removeFirst() / pollFirst():从队列的头部移除并返回元素,如果队列为空,removeFirst会抛出NoSuchElementException,而pollFirst则返回null
  2. removeLast() / pollLast():从队列的尾部移除并返回元素,如果队列为空,removeLast会抛出NoSuchElementException,而pollLast则返回null

3、检查元素

  1. getFirst() / peekFirst():获取但不移除队列头部的元素,如果队列为空,getFirst会抛出NoSuchElementException,而peekFirst则返回null
  2. getLast() / peekLast():获取但不移除队列尾部的元素,如果队列为空,getLast会抛出NoSuchElementException,而peekLast则返回null

Deque接口的使用场景非常广泛,主要包括如下:

  1. 当需要一个可以作为队列(FIFO)或栈(LIFO)使用的数据结构时。
  2. 在需要高效地在两端添加或移除元素的场景中,如实现撤销/重做功能、缓冲区管理等。
  3. 作为其他数据结构的底层实现,如实现一个自定义的栈或队列。

下面是一个简单的代码示例,展示了如何使用Deque接口,如下代码:

import java.util.Deque;  
import java.util.LinkedList;  
  
public class DequeExample {  
    public static void main(String[] args) {  
        Deque<String> deque = new LinkedList<>();  
  
        // 在队列头部添加元素  
        deque.addFirst("Element 1 (Head)");  
          
        // 在队列尾部添加元素  
        deque.addLast("Element 2 (Tail)");  
          
        // 在队列头部继续添加元素  
        deque.offerFirst("Element 0 (Head)");  
          
        // 打印队列元素  
        System.out.println("Deque contents: " + deque);  
          
        // 从队列头部移除并返回元素  
        String removedElement = deque.pollFirst();  
        System.out.println("Removed element from head: " + removedElement);  
          
        // 从队列尾部移除并返回元素  
        removedElement = deque.pollLast();  
        System.out.println("Removed element from tail: " + removedElement);  
          
        // 检查队列头部元素而不移除  
        String headElement = deque.peekFirst();  
        System.out.println("Head element: " + headElement);  
          
        // 检查队列是否为空  
        System.out.println("Deque is empty? " + deque.isEmpty());  
    }  
}

输出将会是:

Deque contents: [Element 0 (Head), Element 1 (Head), Element 2 (Tail)]  
Removed element from head: Element 0 (Head)  
Removed element from tail: Element 2 (Tail)  
Head element: Element 1 (Head)  
Deque is empty? false

在上面代码中,使用了LinkedList类作为Deque接口的实现,因为LinkedList类实现了Deque接口,因此它提供了双端队列的所有操作,向队列中添加了一些元素,然后从头部和尾部移除它们,并检查了队列的头部元素和是否为空。

Queue

代表一个队列数据结构,即一种特殊的线性表,只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,这种操作规则也被称为“先进先出”(FIFO,First-In-First-Out),它的主要功能包括:

1、插入元素:

  1. add(E e):将指定的元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException,不过,在 Queue 接口的实现中,这个方法通常不会抛出异常,因为大多数队列实现都是有界的,但这个界限通常很大。
  2. offer(E e):将指定的元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false

2、移除元素

  1. remove():移除并返回此队列的头部,如果此队列为空,则抛出 NoSuchElementException
  2. poll():移除并返回此队列的头部,或返回 null 如果此队列为空。

3、检查元素

  1. element():检索,但不移除此队列的头部,如果此队列为空,则抛出 NoSuchElementException
  2. peek():检索,但不移除此队列的头部,或返回 null 如果此队列为空。

使用场景

  • 缓冲:当数据需要以有序的方式处理,但又不需要立即处理所有数据时,队列作为缓冲很有用,例如,打印任务队列,网络请求队列等。
  • 生产者-消费者问题:队列经常用于协调多个线程之间的合作,尤其是在生产者-消费者场景中,生产者将产品放入队列,而消费者从队列中取出产品进行消费。
  • 广度优先搜索:在图论中,队列用于实现广度优先搜索(BFS)算法。
  • 事件驱动的系统:队列可以用于存储待处理的事件,例如用户界面事件或系统事件。

代码示例

下面是一个简单的 Queue 接口使用示例,使用了 LinkedList 类作为实现,如下代码:

import java.util.LinkedList;  
import java.util.Queue;  
  
public class QueueExample {  
    public static void main(String[] args) {  
        Queue<String> queue = new LinkedList<>();  
  
        // 插入元素  
        queue.offer("Apple");  
        queue.offer("Banana");  
        queue.offer("Cherry");  
  
        System.out.println("Initial Queue: " + queue);  
  
        // 移除元素  
        String removedElement = queue.poll();  
        System.out.println("Removed Element: " + removedElement);  
        System.out.println("Queue after removal: " + queue);  
  
        // 检查元素  
        String headElement = queue.peek();  
        System.out.println("Head of the Queue: " + headElement);  
  
        // 遍历队列  
        System.out.println("Iterating over the queue:");  
        for (String fruit : queue) {  
            System.out.println(fruit);  
        }  
    }  
}

输出:

Initial Queue: [Apple, Banana, Cherry]  
Removed Element: Apple  
Queue after removal: [Banana, Cherry]  
Head of the Queue: Banana  
Iterating over the queue:  
Banana  
Cherry

在这个示例中,创建了一个 Queue,使用 offer 方法插入了几个元素,使用 poll 方法移除了队列的头部元素,并使用 peek 方法来查看当前队列的头部元素,最后,使用增强for循环遍历了队列中的所有元素。

关注我,每天学习互联网编程技术 - 程序员古德

END!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/379218.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言——oj刷题——调整数组使奇数全部都位于偶数前面

题目&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分。 一、实现方法&#xff1a; 当我们需要对一个整数数组进行调整&#xff0c;使得奇数位于数…

Git详细讲解

文章目录 一、Git相关概念二、本地分支中文件的添加 、提交2.1 文件状态2.2 创建Git仓库2.2.1 git init2.2.2 git clone 2.3 添加操作(git add)2.4 提交操作&#xff08;git commit&#xff09;2.5 撤销操作2.5.1 撤销 add操作2.5.2 撤销 commit操作2.5.3 覆盖上一次的commit操…

机器学习系列——(十八)K-means聚类

引言 在众多机器学习技术中&#xff0c;K-means聚类以其简洁高效著称&#xff0c;成为了数据分析师和算法工程师手中的利器。无论是在市场细分、社交网络分析&#xff0c;还是图像处理等领域&#xff0c;K-means都扮演着至关重要的角色。本文旨在深入解析K-means聚类的原理、实…

EF Core 模型优先——根据类对象创建数据表

需要的nuget包&#xff1a; Microsoft.EntityframeworkCore.SqlServer &#xff08;根据自己的数据库类型选择对应的nuget包&#xff09; Microsoft.EntityframeworkCore.Tools Microsoft.VisualStudio.Web.CodeGeneration.Design 说明&#xff1a; &#xff08;1&#xf…

排序算法---插入排序

原创不易&#xff0c;转载请注明出处。欢迎点赞收藏~ 插入排序是一种简单直观的排序算法&#xff0c;它的基本思想是将待排序的元素分为已排序和未排序两部分&#xff0c;每次从未排序部分中选择一个元素插入到已排序部分的合适位置&#xff0c;直到所有元素都插入到已排序部分…

考研数据结构笔记(3)

顺序表存储结构 存储结构顺序结构定义基本操作的实现静态分配问题 动态分配代码功能 顺序表的特点: 顺序表小结顺序表的插入删除插入删除小结 顺序表的查找按位查找按值查找小结 存储结构 顺序结构 定义 线性表是具有相同数据类型的n(n>0)个数据元素的有限序列(每个数据元素…

大数据 - Spark系列《五》- Spark常用算子

Spark系列文章&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 大数据 - Spark系列《…

vue3 之 组合式API—模版引用

模版引用的概念 通过ref标识获取真实的dom对象或者组件实例对象 如何使用&#xff08;以获取dom为例 组件同理&#xff09; 1️⃣调用ref函数生成一个ref对象 2️⃣通过ref标识绑定ref对象到标签 dom中使用 父组件中可以看到打印出来proxy里面只有一个属性&#xff0c;其他…

Vue中 常用的修饰符有哪些

Vue是一款建立在JavaScript框架上的开源前端库&#xff0c;已经成为当今前端开发人员最喜爱的选择之一。它的简洁语法和强大的功能使得开发者可以轻松地构建交互性的网页应用程序。在Vue中&#xff0c;修饰符是一个重要的概念&#xff0c;它们可以帮助我们更好地控制和定制DOM元…

wyh的迷宫

涉及知识点&#xff1a;求迷宫能否到达终点的&#xff0c;而不是求路径数的&#xff0c;用bfs时可以不用重置状态数组&#xff08;回溯&#xff09;。 题目描述 给你一个n*m的迷宫&#xff0c;这个迷宫中有以下几个标识&#xff1a; s代表起点 t代表终点 x代表障碍物 .代…

【多模态】27、Vary | 通过扩充图像词汇来提升多模态模型在细粒度感知任务(OCR等)上的效果

文章目录 一、背景二、方法2.1 生成 new vision vocabulary2.1.1 new vocabulary network2.1.2 Data engine in the generating phrase2.1.3 输入的格式 2.2 扩大 vision vocabulary2.2.1 Vary-base 的结构2.2.2 Data engine2.2.3 对话格式 三、效果3.1 数据集3.2 图像细粒度感…

数据库管理-第147期 最强Oracle监控EMCC深入使用-04(20240207)

数据库管理147期 2024-02-07 数据库管理-第147期 最强Oracle监控EMCC深入使用-04&#xff08;20240207&#xff09;1 发现Exadata2 Exadata监控计算节点&#xff1a;存储节点RoCE交换机管理交换机PDU 总结 数据库管理-第147期 最强Oracle监控EMCC深入使用-04&#xff08;202402…

网工内推 | 物流、航空业信息安全工程师,CISP认证优先,带薪年假

01 盛辉物流 招聘岗位&#xff1a;网络安全工程师 职责描述: 1、对机房内的网络、系统进行安全扫描和安全防护&#xff0c;上报安全评估报告、日常安全作业计划报告&#xff1b; 2、负责防火墙等安全设备、漏洞扫描工具的维护管理和使用&#xff0c;负责日常安全运维工作及安…

JavaScript相关(一)——作用域

本篇将从JS的执行上下文开始&#xff0c;去理解&#xff1a;变量提升、 栈式调用、作用域和闭包。 参考&#xff1a; 浏览器工作原理与实践 JS执行上下文 执行上下文是 JavaScript 执行一段代码时的运行环境&#xff0c;比如调用一个函数&#xff0c;就会生成这个函数的执行…

【MySQL】_JDBC编程

目录 1. JDBC原理 2. 导入JDBC驱动包 3. 编写JDBC代码实现Insert 3.1 创建并初始化一个数据源 3.2 和数据库服务器建立连接 3.3 构造SQL语句 3.4 执行SQL语句 3.5 释放必要的资源 4. JDBC代码的优化 4.1 从控制台输入 4.2 避免SQL注入的SQL语句 5. 编写JDBC代码实现…

同步和异步、阻塞与非阻塞

一、同步和异步的概念 首先同步和异步是访问数据的机制 同步&#xff1a;同步一般指主动请求并等待IO操作完成的方式异步&#xff1a;主动请求数据后便可以继续处理其它任务&#xff0c;随后等待IO操作完毕的通知 两者的区别&#xff1a;同步会一行一行执行代码&#xff0c;而…

猫头虎分享:什么是IDE?新手入门用哪个IDE比较好?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【集合系列】LinkedHashMap 集合

LinkedHashMap集合 1. 概述2. 方法3. 遍历方式4. 代码示例5. 注意事项 其他集合类 祖父类 Map 父类 HashMap 集合类的遍历方式 具体信息请查看 API 帮助文档 1. 概述 LinkedHashMap 是 Java 中的一种特殊类型的 HashMap&#xff0c;它继承自 HashMap 类&#xff0c;并实现了…

大模型实战营第二期——2. 浦语大模型趣味Demo

文章目录 1. 大模型及InternLM模型介绍2. InternLM-Chat-7B智能对话Demo2.1 基本说明2.2 实际操作2.2.1 创建开发机2.2.2 conda环境配置2.2.3 模型下载2.2.4 InternLM代码库下载和修改2.2.5 cli运行2.2.6 web_demo运行 3. Lagent智能体工具调用Demo3.1 基本说明3.2 实际操作3.2…

Android:Android视图组件

3.1 移动通讯技术 第一代通讯技术:大哥大,工作原理:模拟信号(说话声波引起铜片震动,电容变化,产生交变电流),工作频段(收音机调频,同一个频道才能通讯);缺点:保密性差(同频可以窃听)。 第二代通讯技术:通讯工具变小,工作原理:模拟信号变成数字信号(将声音产…