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

news2024/11/14 19:32:14

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!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RSA算法加密、签名和验签、解密

一、背景介绍 RSA是一种非对称加密算法&#xff0c;该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥&#xff0c;公钥是公开的&#xff08;可能同时多人持有&#xff09;。 二、RSA算法工具类 package com.hl.rsademo.util;import java.i…

MYSQL分区NOW()不支持

传说同事写个复杂的SQL代码,跑一次需要7-10秒, 复杂如上,我也懒得去分析 IF IF IF是怎么回事了! 发现此表是分区表,后面要求加上了分区时间,以便利用到分区裁剪技术. 因为需求是查近10天来到期还款的人和金额.就是今天应该还款的人, 一般还款周期是7天. 给个10天的范围挺可以的…

【DDD】学习笔记-领域实现模型

实现模型与编码质量 领域设计模型体现了类的静态结构与动态协作&#xff0c;领域实现模型则进一步把领域知识与技术实现连接起来&#xff0c;但同时它必须守住二者之间的边界&#xff0c;保证业务与技术彼此隔离。这条边界线应由设计模型明确给出&#xff0c;其中的关键是遵循…

基于SSM的网络在线考试系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的网络在线考试系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring …

数字图像处理实验记录十(图像分割实验)

一、基础知识 1、什么是图像分割 图像分割就是指把图像分成各具特性的区域并提取出感兴趣目标的技术和过程&#xff0c;特性可以是灰度、颜色、纹理等&#xff0c;目标可以对应单个区域&#xff0c;也可以对应多个区域。 2、图像分割是怎么实现的 图像分割算法基于像素值的不连…

Java微服务学习Day1

文章目录 认识微服务服务拆分及远程调用服务拆分服务远程调用提供者与消费者 Eureka注册中心介绍构建EurekaServer注册user-serviceorder-service完成服务拉取 Ribbon负载均衡介绍原理策略饥饿加载 Nacos注册中心介绍配置分级存储负载均衡环境隔离nacos注册中心原理 认识微服务…

《剑指 Offer》专项突破版 - 面试题 30 和 31:详解如何设计哈希表以及利用哈希表设计更加高级、复杂的数据结构

目录 一、哈希表的基础知识 二、哈希表的设计 2.1 - 插入、删除和随机访问都是 O(1) 的容器 2.2 - 最近最少使用缓存 一、哈希表的基础知识 哈希表是一种常见的数据结构&#xff0c;在解决算法面试题的时候经常需要用到哈希表。哈希表最大的优点是高效&#xff0c;在哈希表…

java实现算法

一、二分法 二分法查找主要是为了快速查找给定数组内&#xff0c;期待值在数组中的位置&#xff08;下标&#xff09; 二分法查找通过对整个数组取中间值&#xff0c;判断期待值所在的范围并缩小范围&#xff0c;每次查找范围折半&#xff0c;直到范围的边界重合&#xff0c;…

终端命令提示符:如何查看我们电脑端口是否被占用和处理方式

文章目录 端口信息查看1、Windows:2、Linux/macOS: 使用 netstat使用 lsof 端口信息查看 在不同的操作系统中&#xff0c;查看端口是否被占用的指令有所不同。以下是一些常见的指令&#xff1a; 1、Windows: 使用命令行工具 netstat 来查看端口占用情况。 电脑键盘按住 win…

第九个知识点:内部对象

Date对象: <script>var date new Date();date.getFullYear();//年date.getMonth();//月date.getDate();//日date.getDay();//星期几date.getHours();//时date.getMinutes();//分date.getSeconds();//秒date.getTime();//获取时间戳&#xff0c;时间戳时全球统一&#x…

[计算机提升] 备份系统:系统映像

6.3 备份系统&#xff1a;系统映像 备份系统和还原系统是一套互补的操作。 操作系统的备份就是将操作系统当前的所有数据复制到硬盘的一个空闲区域&#xff0c;以防止系统崩溃或数据丢失。还原操作则是将先前备份的数据恢复到操作系统中&#xff0c;使系统回到之前的样子&…

Python进程之串行与并行

串行和并行 串行指的是任务的执行方式。串行在执行多个任务时&#xff0c;各个任务按顺序执行&#xff0c;完成一个之后才能进行下一个。&#xff08;早期单核CPU的情况下&#xff09; 并行指的是多个任务在同一时刻可以同时执行&#xff08;前提是多核CPU&#xff09;&#…

蓝桥杯备赛Day9——链表进阶

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5]示例 2: 输入:head = [1], n = 1 输出:[]示例 3: 输入:head = [1,2], n = 1 输出:[1]提示: 链表中结点的数目为 sz1 <= sz <= 300 &l…

2024-02-07(Sqoop,Flume)

1.Sqoop的增量导入 实际工作中&#xff0c;数据的导入很多时候只需要导入增量的数据&#xff0c;并不需要将表中的数据每次都全部导入到hive或者hdfs中&#xff0c;因为这样会造成数据重复问题。 增量导入就是仅导入新添加到表中的行的技术。 sqoop支持两种模式的增量导入&a…

sqli.labs靶场(41-53关)

41、第四十一关 -1 union select 1,2,3-- -1 union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schemadatabase()) -- -1 union select 1,2,(select group_concat(column_name) from information_schema.columns wher…

2024年【天津市安全员B证】模拟试题及天津市安全员B证模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 天津市安全员B证模拟试题是安全生产模拟考试一点通生成的&#xff0c;天津市安全员B证证模拟考试题库是根据天津市安全员B证最新版教材汇编出天津市安全员B证仿真模拟考试。2024年【天津市安全员B证】模拟试题及天津市…

零基础学Python之Unitest模块

1.unittest简介及入门案例 &#xff08;1&#xff09;什么是Unitest Unittest是Python自带的单元测试框架&#xff0c;不仅适用于单元测试&#xff0c;还可用于Web、Appium、接口自动化测试用例的开发与执行。该测试框架可组织执行测试用例&#xff0c;并且提供丰富的断言方法…

如何使用CLZero对HTTP1.1的请求走私攻击向量进行模糊测试

关于CLZero CLZero是一款功能强大的模糊测试工具&#xff0c;该工具可以帮助广大研究人员针对HTTP/1.1 CL.0的请求走私攻击向量进行模糊测试。 工具结构 clzero.py - 工具主脚本&#xff1b; default.py - 包含了大多数标准攻击测试方法和字符&#xff1b; exhaustive.py - 包…

Git介绍和常用命令说明

目录 一、Git概述 1.1 Git是什么 1.2 Git有什么用 1.3 Git仓库介绍 二、Git下载与安装 三、Git代码托管服务&#xff08;远程仓库&#xff09; 四、Git常用命令 4.1 设置用户信息 4.2 获取Git仓库 4.2.1 本地初始化Git仓库 4.2.2 从远程仓库克隆 4.3 本地仓库操作 …

navigator.mediaDevices.getUserMedia获取本地音频/麦克权限并提示用户

navigator.mediaDevices.getUserMedia获取本地音频/麦克权限并提示用户 效果获取权限NotFoundErrorNotAllowedError 代码 效果 获取权限 NotFoundError NotAllowedError 代码 // 调用 captureLocalMedia()// 方法 function captureLocalMedia() {console.warn(Requesting lo…