java-02 数据结构-队列

news2024/12/23 7:23:59

  在Java中,队列是一种常见的数据结构,用于在保持顺序的同时存储和检索数据。Java提供了java.util.Queue接口,它的常见实现包括ArrayDeque、LinkedList和PriorityQueue等。

如果你觉得我分享的内容或者我的努力对你有帮助,或者你只是想表达对我的支持和鼓励,请考虑给我点赞、评论、收藏。您的鼓励是我前进的动力,让我感到非常感激。

文章目录

  • 1 java中队列简述
  • 2 在Java中有哪些常见的队列
  • 3 重点队列分析
    • 3.1 Queue 接口分析
    • 3.2 Deque 接口分析
    • 3.3 PriorityQueue 的实现原理详解
  • 4 队列的分类
    • 4.1 Queue队列
    • 4.2 双端队列
    • 4.3 阻塞队列
    • 4.4 非阻塞队列
  • 5 各队列的区别与联系

1 java中队列简述

队列是一种由数组和链表作为底层构造的只暴露头和尾操作API的数据结构,因此,队列是被认为是一种受限的数据结构。
请添加图片描述
补充:集合体系简图
请添加图片描述

2 在Java中有哪些常见的队列

在Java中,有一些常见的队列实现。下面是其中一些的列举://队列也是一种线性的数据结构

  • ArrayList:ArrayList可以被用作队列,通过在列表末尾添加元素,并使用remove(0)方法从列表的开头删除元素。但是,由于在列表的开头删除元素会导致后续元素的移动,因此对于大量的插入和删除操作来说,ArrayList的性能可能不是最佳选择。
  • LinkedList:LinkedList也可以用作队列。LinkedList实现了Queue接口,可以使用offer()方法在队列的末尾添加元素,使用poll()方法从队列的开头删除并返回元素。LinkedList对于插入和删除操作具有较好的性能,因为它使用了指针来链接元素,而不需要移动其他元素。
  • ArrayBlockingQueue:ArrayBlockingQueue是一个有界阻塞队列,底层使用数组实现。它有一个固定的容量,并且在插入或删除元素时可能会阻塞线程,直到满足特定的条件。
  • LinkedBlockingQueue:LinkedBlockingQueue是一个可选有界或无界的阻塞队列,底层使用链表实现。它具有类似于- ArrayBlockingQueue的功能,但在内部实现上略有不同。
  • PriorityBlockingQueue:PriorityBlockingQueue是一个支持优先级的无界阻塞队列。元素按照它们的优先级顺序被插入和删除。
  • ConcurrentLinkedQueue:ConcurrentLinkedQueue是一个非阻塞无界队列,它适用于多线程环境。它使用链表实现,并且提供了高效的并发操作。

3 重点队列分析

3.1 Queue 接口分析

  Queue接口是Java集合框架中定义的一个接口,它代表了一个先进先出(FIFO)的队列。Queue接口继承自Collection接口,它定义了一组方法来操作队列中的元素。下面是Queue接口的一些主要方法和特性的详细解释:

(1)添加元素:
boolean add(E element): 将指定的元素添加到队列的末尾,如果成功则返回true,如果队列已满则抛出异常。
boolean offer(E element): 将指定的元素添加到队列的末尾,如果成功则返回true,如果队列已满则返回false。
(2)移除元素:
E remove(): 移除并返回队列头部的元素,如果队列为空则抛出异常。
E poll(): 移除并返回队列头部的元素,如果队列为空则返回null。
(3)获取头部元素:
E element(): 获取队列头部的元素,但不移除它,如果队列为空则抛出异常。
E peek(): 获取队列头部的元素,但不移除它,如果队列为空则返回null。
(4)队列大小:
int size(): 返回队列中的元素个数。
boolean isEmpty(): 判断队列是否为空。

  Queue接口还有一些其他方法,如clear()用于清空队列中的所有元素,contains(Object o)用于判断队列是否包含指定元素等。Queue接口的常见实现类包括LinkedList、ArrayDeque和PriorityQueue等。LinkedList实现了Queue接口,并且还可以作为栈使用,它是一个双向链表。ArrayDeque是一个双端队列,它同时实现了Queue和Deque接口。PriorityQueue是一个基于优先级的队列,它允许元素按照优先级顺序被插入和删除。 通过使用Queue接口,我们可以方便地进行队列操作,如入队、出队、查看队列头部元素等。它在处理任务调度、消息传递等场景中非常有用。

3.2 Deque 接口分析

  Deque接口是Java集合框架中定义的一个接口,它代表了一个双端队列(Double Ended Queue)。Deque是"双端队列"的缩写。Deque接口继承自Queue接口,并在其基础上提供了在队列两端进行添加、删除和检索元素的操作。Deque可以在队列的头部和尾部同时进行元素的插入和删除,因此可以作为队列、栈或双向队列使用。

Deque接口定义了以下主要方法和特性:
(1)添加元素:
void addFirst(E element): 将指定元素添加到双端队列的头部。
void addLast(E element): 将指定元素添加到双端队列的尾部。
boolean offerFirst(E element): 将指定元素添加到双端队列的头部,如果成功则返回true,如果队列已满则返回false。
boolean offerLast(E element): 将指定元素添加到双端队列的尾部,如果成功则返回true,如果队列已满则返回false。
(2)移除元素:
E removeFirst(): 移除并返回双端队列的头部元素,如果队列为空则抛出异常。
E removeLast(): 移除并返回双端队列的尾部元素,如果队列为空则抛出异常。
E pollFirst(): 移除并返回双端队列的头部元素,如果队列为空则返回null。
E pollLast(): 移除并返回双端队列的尾部元素,如果队列为空则返回null。
(3)获取头部和尾部元素:
E getFirst(): 获取双端队列的头部元素,但不移除它,如果队列为空则抛出异常。
E getLast(): 获取双端队列的尾部元素,但不移除它,如果队列为空则抛出异常。
E peekFirst(): 获取双端队列的头部元素,但不移除它,如果队列为空则返回null。
E peekLast(): 获取双端队列的尾部元素,但不移除它,如果队列为空则返回null。

   Deque接口还提供了一些其他方法,如size()用于返回双端队列中的元素个数,isEmpty()用于判断双端队列是否为空,clear()用于清空双端队列中的所有元素等。通过使用Deque接口,我们可以方便地进行双端队列操作,如在队列的头部和尾部插入和删除元素,获取头部和尾部元素,以及判断队列是否为空。Deque在许多场景下都很有用,比如实现LRU缓存、实现任务调度等。

   另外,需要注意的是,Deque接口还可以用作栈(LIFO)的数据结构。通过在队列头部执行插入和删除操作,可以实现栈的功能。常见的栈操作可以使用Deque接口中的以下方法来实现:

void push(E element): 将元素推入栈顶,等同于addFirst(E element)。
E pop(): 弹出并返回栈顶元素,等同于removeFirst()。
E peek(): 获取栈顶元素,等同于peekFirst()。

   所以,Deque接口是一个非常有用的接口,提供了双端队列的功能,既可以在队列的头部进行操作,也可以在尾部进行操作。它是Queue接口的扩展,可以方便地实现队列、栈和双向队列的功能,并提供了丰富的方法来操作和访问队列中的元素。

3.3 PriorityQueue 的实现原理详解

PriorityQueue的实现原理是基于二叉堆(Binary Heap),它是一种特殊的完全二叉树结构,具有以下性质:

  • PriorityQueue 一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。
  • PriorityQueue允许元素具有相同的优先级,但它们的顺序不一定是确定的。在这种情况下,PriorityQueue的行为是不保证的,具有相同优先级的元素可能会以任意顺序被取出。
  • PriorityQueue 是非线程安全的,在多线程情况下可使用 PriorityBlockingQueue类替代;
    public static void main(String[] args) {
        //默认采用的是最小堆实现的
        PriorityQueue<Integer> queue = new PriorityQueue<Integer>(10, new Comparator<Integer>() {
            public int compare(Integer a, Integer b) {
                return a - b; //if a>b 则交换,so这是递增序列
            }
        });
        queue.offer(13);
        queue.offer(9);
        int len = queue.size();
        for (int i = 0; i < len; i++) {
            System.out.println(queue.poll());
        }

        //输出 9  13
        //默认采用的是最小堆实现的
        PriorityQueue<Integer> queue2 = new PriorityQueue<>(10);
        queue2.offer(11);
        queue2.offer(9);
        len = queue2.size();
        for (int i = 0; i < len; i++) {
            System.out.println(queue2.poll());
        }
        //输出 9, 11
    }

4 队列的分类

4.1 Queue队列

Queue是java中实现队列的接口,它总共只有6个方法,如下:
Queue的6个方法分类:

  • 压入元素(添加):add()、offer()
    相同:未超出容量,从队尾压入元素,返回压入的那个元素。
    区别:在超出容量时,add()方法会对抛出异常,offer()返回false
  • 弹出元素(删除):remove()、poll()
    相同:容量大于0的时候,删除并返回队头被删除的那个元素。
    区别:在容量为0的时候,remove()会抛出异常,poll()返回false
  • 获取队头元素(不删除):element()、peek()
    相同:容量大于0的时候,都返回队头元素。但是不删除。
    区别:容量为0的时候,element()会抛出异常,peek()返回null。
    在这里插入图片描述

4.2 双端队列

deque 是“double ended queue(双端队列)”的缩写,通常读为“deck”。双端队列顾名思义就是队列的两个端口都能进出。
Deque的实现类是LinkedList,ArrayDeque,LinkedBlockingDeque,其中LinkedList是最常用的。值得注意的是,LinkedList也实现了List接口。大多数Deque既可以是有容量限制也可以是无固定容量限制。
在这里插入图片描述


由于双端队列的既能实现先进先出,也能实现先进后出,因此,双端队列一般有三种用途:

// 作为普通队列(先进先出)
Queue queue = new LinkedList()Deque deque = new LinkedList()
// 作为堆栈(先进后出)
Deque deque = new LinkedList()
// 作为双端队列(两端可进出)
Deque deque = new LinkedList()

以下是双端队列与堆栈方法的等效方法对比:
在这里插入图片描述

4.3 阻塞队列

1、理解
阻塞队列是一个支持两个附加操作的队列,即在队列为满时,存储元素的线程会等待队列可用,当队列为空时,获取元素的线程会等待队列为非空。

2、Java中的阻塞队列
阻塞队列接口有BlockingQueue和BlockingDeque两个,其中后者是双向队列。
其中BlockingQueue接口提供的方法如下:
在这里插入图片描述
BlockingDeque接口提供的方法如下:
头部元素:
在这里插入图片描述
尾部元素:
在这里插入图片描述

3 常见的阻塞队列有:
ArrayBlockingQueue : 一个由数组结构组成的有界阻塞队列。
LinkedBlockingQueue : 一个由链表结构组成的有界阻塞队列。
PriorityBlockingQueue : 一个支持优先级排序的无界阻塞队列。
DelayQueue: 一个使用优先级队列实现的无界阻塞队列。
SynchronousQueue: 一个不存储元素的阻塞队列。
LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列

具体的实现方法没有深究,有兴趣的可以看引用资料:阻塞队列详解

4.4 非阻塞队列

1、理解
非阻塞队列不能阻塞,个人理解为普通队列,在多线程中,当队列满或空时,只能使用wait()和notify()进行队列消息传送。

2、Java中的非阻塞队列
AbstractQueue是非阻塞队列的接口,常见的非阻塞实现类有:

  • (1)LinkedList
    既实现了AbstractQueue接口也实现了Deque接口,也可作为双端队列使用。
  • (2)PriorityQueue
    该类维护了一个有序队列,默认队头是规则排序中最小的元素,若多个最小值,则随机挑选。
    排序的规则是通过构造函数comparator来实现,因此,该队列不允许插入null值或不可比较的对象。
  • (3)ConcurrentLinkedQueue
    该类是基于链接点的线程安全队列,并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大小,ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。此队列不允许使用null元素,

3、操作方法
add(E e):将元素 e 插入到队列末尾,如果插入成功,则返回 true;如果插入失败(即队列已满),则会抛出异常;
remove():移除队首元素,若移除成功,则返回 true;如果移除失败(队列为空),则会抛出异常;
remove(Object o):移除指定的元素,若移除成功,则返回 true;如果移除失败(队列为空),则会抛出异常
offer(E e):将元素 e 插入到队列末尾,如果插入成功,则返回 true;如果插入失败(即队列已满),则返回 false;
poll():移除并获取队首元素,若成功,则返回队首元素;否则返回 null;
peek():获取队首元素,若成功,则返回队首元素;否则返回 null
isEmpty():队列是否为空
size():队列长度

值得注意的是,一般情况下建议使用 offer、poll 和 peek 三个方法,不建议使用 add 和 remove 方法。因为使用 offer、poll 和 peek 三个方法可以通过返回值判断操作成功与否,而使用 add 和 remove 方法却不能达到这样的效果。
尤其对于插入操作,往往使用返回特殊值的方法。

5 各队列的区别与联系

以下为个人理解,不正确请指正。
1、从数据的输入和输出角度来看,队列可以看成是普通和双端两种,普通队列是先进先出,而双端则可以两端进出。
2、从并发角度来看,队列可以看成阻塞和非阻塞两种,阻塞队列能实现阻塞,而非阻塞不能阻塞,阻塞和非阻塞队列都有普通队列和双端队列特性的实现类。

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

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

相关文章

元数据 - iXML

在专业的音频和视频制作中&#xff0c;元数据的准确传递对于后期制作和编辑至关重要。iXML&#xff08;iXML Metadata&#xff09;是一种开放的、可扩展的元数据规范&#xff0c;旨在在录音设备和数字音频工作站&#xff08;DAW&#xff09;之间传递详细的录音信息。 一、什么是…

安卓使用.9图实现阴影效果box-shadow: 0 2px 6px 1px rgba(0,0,0,0.08);

1.安卓实现阴影效果有很多种&#xff0c;一般UX设计会给以H5参数box-shadow: 0 2px 6px 1px rgba(0,0,0,0.08);这种方式提供背景阴影效果&#xff0c;这里记录一下实现过程 2.界面xml源码 <?xml version"1.0" encoding"utf-8"?> <layout xmlns…

小北的技术博客:探索华为昇腾CANN训练营与AI技术创新——Ascend C算子开发能力认证考试(中级)

前言 哈喽哈喽,这里是zyll~,北浊.(大家可以亲切的呼唤我叫小北)智慧龙阁的创始人,一个在大数据和全站领域不断深耕的技术创作者。今天,我想和大家分享一些关于华为昇腾CANN训练营以及AI技术创新的最新资讯和实践经验~(初级证书还没拿到的小伙伴,可以先参考小北的这篇技术…

QTableView-mode中嵌入复选框CheckBox

QTableView中嵌入复选框CheckBox 第二种方法&#xff1a;设置QAbstractTableModel的flags()函数法 通过Delegate创建QCheckBox来实现的Check列&#xff0c;只有在该列进入编辑模式时才能够Check/Uncheck。这显然不是我们想要的&#xff0c;网上翻来翻去&#xff0c;在一个国外论…

SpringBoot+Vue智能社区服务小程序

SpringBootVue智能社区服务小程序 SpringBootVue智能社区服务小程序 项目描述 智能社区服务小程序的前台小程序是一个集成多功能的综合性平台&#xff0c;旨在提供便捷、高效的社区服务。以下是关于各个功能的简单介绍&#xff1a; 用户管理&#xff1a;用户管理模块负责社区…

基于SpringBoot+Vue的非物质文化遗产保护与传播系统设计实现【原创】(地图组件)

&#x1f388;系统亮点&#xff1a;地图组件&#xff1b; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17 前端&#xff1a; 技术&#xff1a;框架Vue.js&#x…

Mysql(五) --- 数据库设计

文章目录 前言1.范式1.1.第一范式1.1.1 定义1.1.2.例子 1.2.第二范式1.2.1 定义1.2.2 例子1.2.3.不满足第二范式可能会出现的问题 1.3.第三范式1.3.1 定义2.3.2 示例 2. 设计过程3. 实体-关系图3.1 E-R图的基本组成3.2 关系的类型3.2.1 一对一关系(1:1)3.2.2 ⼀对多关系(1:N)3.…

Mac 需要杀毒软件?

大部分 mac用户普遍认为 Apple mac 不受病毒和恶意软件的影响。这导致许多 Mac 用户误以为无需为 Mac 安装防病毒软件&#xff0c;但事实并非如此。 在这篇文章中&#xff0c;将深入探讨 Mac 安全性的细节&#xff0c;探索针对 Apple 设备的恶意软件类型&#xff0c;并为您…

高质量SCI论文撰写及投稿丨论文选题、文献调研、实验设计、数据分析、论文结构及语言规范等----AI强大功能

科学研究的核心在于将复杂的思想和实验成果通过严谨的写作有效地传递给学术界和工业界。对于研究生、青年学者及科研人员&#xff0c;如何高效撰写和发表SCI论文&#xff0c;成为提升学术水平和科研成果的重要环节。系统掌握从选题到投稿的全过程&#xff0c;提高论文撰写效率与…

petalinux 自动登陆 自动启动程序

PetaLinux 自动登陆 (1) cd 到项目工程目录下&#xff1b; (2) 运行命令&#xff1a;petalinux-config -c rootfs (3) 依次选择 Image Features -> serial-autologin-root 保存退出 创建APP petalinux-create apps --template install --name init-app --enable编辑文件 …

【环境搭建】MAC M1安装ElasticSearch

STEP1 官网下载ES Download Elasticsearch | Elastic&#xff0c;下载mac m1对应版本的es STEP2 进入bin文件夹&#xff0c;执行./elasticSearch 浏览器输入 127.0.0.1:9200 STEP 3 下载对应Kibana版本&#xff0c;Download Kibana Free | Get Started Now | Elastic 出现报错…

微信点赞的测试用例,应该在哪些方面进行设计!

功能模块测试的测试用例设计方法包括&#xff1a; 等价类划分法&#xff1a;把所有可能的输入数据&#xff0c;即程序的输入域划分成若干部分&#xff0c;然后从每一个部分中选取少数具有代表性的数据作为测试用例。比如字符串长度检查,字符类型检查,标点符号检查,特殊字符检查…

使用 Docker 部署前端项目:Vue 和 React 结合 Nginx 实现静态文件托管

使用 Docker 部署前端项目&#xff1a;Vue 和 React 结合 Nginx 实现静态文件托管 Web 开发中&#xff0c;将前端项目&#xff08;例如 Vue 或 React 应用&#xff09;打包后通过 Docker 容器和 Nginx 部署是非常常见的方式。它不仅简化了部署流程&#xff0c;还能确保在不同环…

linux线程 | 线程的概念

前言:本篇讲述linux里面线程的相关概念。 线程在我们的教材中的定义通常是这样的——线程是进程的一个执行分支。 线程的执行粒度&#xff0c; 要比进程要细。 我们在读完这句话后其实并不能很好的理解什么是线程。 所以&#xff0c; 本节内容博主将会带友友们理解什么是线程&a…

Vulnhub靶场案例渗透[6]- DC6

文章目录 1. 靶场搭建2. 信息收集2.1 确定靶机ip2.2 主机信息收集2.3 主机目录扫描2.4 网站用户名和密码爆破 3. 反弹shell4. 提权 1. 靶场搭建 靶场源地址 检验下载文件的检验码&#xff0c;对比没问题使用vmware打开 # windwos 命令 Get-FileHash <filePath> -Algori…

RTSP 音视频play同步分析

基础理论 RTSP RTP RTCP SDP基础知识-CSDN博客 关于RTP的时间戳知识点回顾 时间戳单位&#xff1a;时间戳计算的单位不是秒&#xff0c;而是采用采样频率的倒数&#xff0c;这样做的目的是为了使时间戳单位更为精准。比如说一个音频的采样频率为8000Hz&#xff0c;那么我们可…

【华为】基于华为交换机的VLAN配置与不同VLAN间通信实现

划分VLAN&#xff08;虚拟局域网&#xff09;主要作用&#xff1a; 一、提高网络安全性 广播域隔离访问控制增强 二、优化网络性能 减少网络拥塞提高网络可管理性 sysytem-view #进入系统视图配置参数 vlan batch 10 20 #批量创建vlan LSW3: int g0/0/1 port…

「实战应用」如何用图表控件LightningChart可视化天气数据?(一)

LightningChart.NET完全由GPU加速&#xff0c;并且性能经过优化&#xff0c;可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D&#xff0c;高级3D&#xff0c;Polar&#xff0c;Smith&#xff0c;3D饼/甜甜圈&#xff0c;地理地图和GIS图表以及适用于科学…

scau:面向对象java实验作业1-2 猜数字游戏

题目名称实验1-2 猜数字游戏题目关键字数据类型 基本输入输出 控制语句 方法题目录入时间2022/10/10 11:01:37题目内容 使用Java程序&#xff0c;项目名称&#xff1a;GuessNumberGame&#xff0c;类根据自己需要定义。 程序开始运行后&#xff0c;允许玩家进行多次猜数字的游…

C++从入门到起飞之——(multi)set与(multi)map的的使用 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1. 序列式容器和关联式容器 2. set系列的使⽤ 2.1 set和multiset参考⽂档 2.2 set类的介绍 2.3 se…