Java中PriorityQueue的用途和性能深度剖析

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在开发中,我们经常需要对元素进行排序,并且可以快速访问最小或最大元素。这个时候,PriorityQueue就成了我们的不二选择。PriorityQueue是一个基于优先级堆的无界优先级队列。根据不同的构造函数,可以将PriorityQueue定义为小根堆和大根堆。

摘要

  本文将重点介绍Java中的PriorityQueue类。我们将深入探讨PriorityQueue类的用法,它的优缺点,以及一些常见的应用场景,最主要的还是会通过实例结合知识点给大家侧面剖析,理论结合实践,以保障大家能够理解的更为透彻。

PriorityQueue

简介

  PriorityQueue可以被认为是一个数组,但它具有一些额外的限制。首先,PriorityQueue的大小是固定的,而且只能在初始化的时候设置。其次,PriorityQueue不允许使用索引来访问元素,因此我们不能查看PriorityQueue中的第k个元素。相反,PriorityQueue中的元素都是按照优先级排列的,并且可以使用poll()方法快速获取优先级最高的元素。

源代码解析

public class PriorityQueue<E extends Comparable<? super E>> extends AbstractQueue<E> implements Serializable {
    //...
}

  从上面的代码可以看出,PriorityQueue是一个继承了AbstractQueue类并实现了Serializable接口的泛型类。在Java中,泛型是一种强类型编程机制,它可以在编译时对类型进行检查并确定类型安全。在PriorityQueue中,使用了泛型<E extends Comparable<? super E>>来限制元素类型,确保元素类型实现了Comparable接口,也就是说元素可以进行比较。

在这里插入图片描述

PriorityQueue中有一个关键的成员变量,即堆数组:

private transient Object[] queue;

  在PriorityQueue中,堆数组实际上是用来存储所有元素的。堆数组中的下标从1开始,因为堆数组中的第一个元素在下标1处。当我们添加一个元素时,它将被添加到堆数组的最后一个位置。然后,我们必须保证堆数组中元素的顺序是按照优先级来排序的,如果不是,我们就需要重新排列堆数组。在实现堆排序时,我们通常使用一组siftUp()siftDown()方法(也称为percolateUp()percolateDown())。

  • siftUp()方法

  siftUp()方法是将刚添加的元素上浮到合适的位置。它的实现方法类似于冒泡排序方法。当我们添加一个元素时,它将被添加到堆数组的末尾,然后我们不断地比较它和它的父节点,并交换它们的位置,直到它的父节点小于等于它或者到达根节点位置。

在这里插入图片描述

  • siftDown()方法

  siftDown()方法是将根节点下沉到合适的位置。当我们删除一个元素时,它会被堆数组的最后一个元素替换,然后我们将根节点下沉到合适的位置以维护堆的有序性。与siftUp()方法类似,siftDown()方法不断地比较当前节点和它的子节点,并交换它们的位置,直到当前节点小于等于最小的子节点或子节点都为空。

应用场景案例

  PriorityQueue可以用于需要对元素按照优先级排序的场景。以下是一些使用PriorityQueue的常见场景:

  • 模拟任务调度系统:可以将所有任务按照优先级放入PriorityQueue中,并使用poll()方法获取下一个要执行的任务。
  • 合并多个有序数组:可以将多个有序数组的第一个元素放入PriorityQueue中,并且每次从PriorityQueue中取出最小的元素,直到PriorityQueue为空。
  • 实现Dijkstra最短路径算法:可以将所有顶点按照距离起点的距离放入PriorityQueue中,并使用poll()方法获取到达下一个顶点的最短路径。

优缺点分析

优点:

  1. PriorityQueue可以高效地维护元素的有序性,它内部使用堆排序算法来维护元素的顺序。
  2. PriorityQueue可以用于需要快速访问最小或最大元素的场景。
  3. PriorityQueue可以通过指定Comparator来按照自定义的优先级来进行排序。

缺点:

  1. PriorityQueue不允许使用索引来访问元素,因此我们不能查看PriorityQueue中的第k个元素。
  2. PriorityQueue的大小是固定的,而且只能在初始化的时候设置。
  3. PriorityQueue不是线程安全的,如果需要线程安全的优先级队列,可以使用ConcurrentPriorityQueue类。

类代码方法介绍

构造方法

  • PriorityQueue():创建一个空的PriorityQueue,初始容量为11,按照元素的自然顺序进行排序。
  • PriorityQueue(int initialCapacity):创建一个空的PriorityQueue,初始容量为initialCapacity,按照元素的自然顺序进行排序。
  • PriorityQueue(int initialCapacity, Comparator<? super E> comparator):创建一个空的PriorityQueue,初始容量为initialCapacity,按照指定的comparator进行排序。
  • PriorityQueue(Collection<? extends E> c):创建一个包含c中所有元素的PriorityQueue,按照元素的自然顺序进行排序。
  • PriorityQueue(PriorityQueue<? extends E> c):创建一个包含c中所有元素的PriorityQueue,按照PriorityQueue中元素的自然顺序进行排序。
  • PriorityQueue(SortedSet<? extends E> c):创建一个包含c中所有元素的PriorityQueue,按照c的比较顺序进行排序。

方法

  • boolean add(E e):添加指定元素到PriorityQueue中。
  • void clear():从PriorityQueue中移除所有元素。
  • Comparator<? super E> comparator():返回PriorityQueue中元素的排序方式。
  • boolean contains(Object o):检查PriorityQueue中是否包含指定的元素。
  • Iterator iterator():返回PriorityQueue中元素的迭代器,按照元素的自然顺序进行排序。
  • boolean offer(E e):添加指定元素到PriorityQueue中。
  • E peek():返回PriorityQueue中的第一个元素,如果PriorityQueue为空,则返回null。
  • E poll():移除并返回PriorityQueue中的第一个元素,如果PriorityQueue为空,则返回null。
  • boolean remove(Object o):从PriorityQueue中移除指定元素。
  • int size():返回PriorityQueue中的元素个数。
  • Object[] toArray():将PriorityQueue中的元素转换为数组。
  • T[] toArray(T[] a):将PriorityQueue中的元素转换为指定类型的数组。

测试用例

下面是一些测试代码,测试PriorityQueue的基本功能:

测试代码演示

package com.example.javase.collection;

import java.util.PriorityQueue;

/**
 * @Author ms
 * @Date 2023-10-24 18:47
 */
public class PriorityQueueTest {

    public static void main(String[] args) {
        // 创建一个PriorityQueue
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        // 添加元素
        pq.offer(1);
        pq.offer(3);
        pq.offer(2);

        // 获取元素
        System.out.println(pq.poll()); // 1
        System.out.println(pq.poll()); // 2
        System.out.println(pq.poll()); // 3

        // 检查是否为空
        System.out.println(pq.isEmpty()); // true
    }
}

测试结果

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

在这里插入图片描述

代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。
  如上测试用例演示了使用Java中的PriorityQueue类进行优先级队列的操作。在代码中,首先创建了一个PriorityQueue对象pq,然后通过调用pq.offer()方法添加了三个整数元素1、3和2。接着调用pq.poll()方法获取队列中的元素,由于PriorityQueue是一个优先级队列,因此获取的元素将会按照从小到大的顺序依次弹出,即先弹出1,再弹出2,最后弹出3。最后通过pq.isEmpty()方法检查队列是否为空,输出结果为true,证明队列已经为空。

全文小结

  本文介绍了Java中的PriorityQueue类,它是一个基于优先级堆的无界优先级队列。我们深入探讨了PriorityQueue类的源代码解析,它的优缺点,以及一些常见的应用场景。我们还介绍了PriorityQueue类的构造方法和方法,并提供了一些测试用例。在开发中,我们可以用PriorityQueue来模拟任务调度系统、合并多个有序数组以及实现Dijkstra最短路径算法等场景。

总结

  • PriorityQueue是一个基于优先级堆的无界优先级队列,可以用于需要对元素按照优先级排序的场景。
  • PriorityQueue内部使用堆排序算法来维护元素的顺序,可以高效地维护元素的有序性。
  • PriorityQueue不允许使用索引来访问元素,因此不能查看PriorityQueue中的第k个元素。
  • PriorityQueue的大小是固定的,而且只能在初始化的时候设置。
  • PriorityQueue不是线程安全的,如果需要线程安全的优先级队列,可以使用ConcurrentPriorityQueue类。
  • PriorityQueue的构造方法和方法较多,可以根据实际需求选择合适的构造方法和方法。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

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

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

相关文章

大势已至,智慧广西 | 大势智慧到往广西自然资源厅下属多家事业单位汇报交流

5月9-10日&#xff0c;武汉大势智慧科技有限公司&#xff08;后简称“大势智慧”&#xff09;CEO黄先锋一行先后到往广西壮族自治区地理信息测绘院&#xff08;后简称“地测院”&#xff09;、广西壮族自治区地图院&#xff08;后简称“地图院”&#xff09;、广西壮族自治区自…

组合模式(结构型)

目录 一、前言 二、透明组合模式 三、安全组合模式 四、总结 一、前言 组合模式(Composite Pattern)是一种结构型设计模式&#xff0c;将对象组合成树形结构以表示“部分-整体”得层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 组合模式由以下角色组成…

Jmeter内存溢出原因及解决办法

现在越来越多的小伙伴在压力测试过程中选择使用Jmeter&#xff0c;原因是这个工具开源且小巧&#xff0c;而且还支持二次开发。 但是事情都有两面性&#xff0c;利弊共存啊&#xff0c;对比商业软件Loadrunner&#xff0c;Jmeter在高并发&#xff0c;特别是大型项目的高并发&a…

将macOS系统安装到外置硬盘上教程

常常因为Mac昂贵的价格&#xff0c;我们会选择低容量的硬盘版本&#xff0c;造成很多大型游戏都安装不了的尴尬境地。今天&#xff0c;我们要探讨一个非常实用的话题&#xff1a;如何给你的Mac电脑扩容&#xff0c;通过将macOS系统安装到外置硬盘上。这对于希望提升存储空间但又…

计算机组成原理(超详解!!) 第七节 中央处理器(下)

1.微程序控制器 微程序设计技术&#xff1a;利用软件方法来设计硬件的一门技术。 微程序控制器的基本思想&#xff1a; 仿照通常的解题程序的方法&#xff0c;把操作控制信号编成所谓的“微指令”&#xff0c;存放到一个只读存储器里。当机器运行时&#xff0c;一条又一条地…

安全测试工具BurpSuite安装和使用

1.安装 下载地址&#xff1a;https://pan.baidu.com/s/1YJbZGAfVKLsQmNeZYZXEeQ 提取码: yyds 打开cmd&#xff0c;运行以下指令&#xff0c;打开keygen界面&#xff1a; java -jar "C:\soft\BurpSuite v2.1\burp-loader-keygen-2.jar" 点击Run按钮&#xff0c;弹…

5月13号作业

使用消息队列实现的2个终端之间的互相聊天 并使用信号控制消息队列的读取方式&#xff1a; 当键盘按ctrlc的时候&#xff0c;切换消息读取方式&#xff0c;一般情况为读取指定编号的消息&#xff0c;按ctrlc之后&#xff0c;指定的编号不读取&#xff0c;读取其他所有编号的消息…

标准输入输出流(中北大学-程序设计基础(2))

目录 题目 源码 结果示例 题目 输入三角形的三边a,b,c&#xff0c;计算三角形的面积。形成三角形的条件是ab>c,bc>a,ac>b&#xff0c;编写程序&#xff0c;输入a,b,c&#xff0c;检查a,b,c是否满足以上条件&#xff0c;如不满足&#xff0c;由cerr输出有关出错信息…

开眼了,自动化测试还能这样用?

持续集成的自动化测试通常需要将代码、测试用例与持续集成工具进行绑定&#xff0c;以实现自动运行。然而&#xff0c;Apipost的自动化测试功能需要手动操作&#xff0c;并且需要手动查看测试结果。 为了解决这个问题&#xff0c;Apipost推出了持续集成功能&#xff0c;方便同…

基于SpringBoot的酒店(预约)客房管理系统的设计与实现+毕业论文

系统介绍 酒店客房管理系统为酒店管理者和用户、清洁人员提供一个在线管理酒店客房的系统。在网站的设计中&#xff0c;一共分为了两个模块设计&#xff0c;一个是前台模块&#xff0c;一个是后台模块&#xff0c;前台主要用于提供查看客房信息&#xff0c;酒店资讯&#xff0…

计算礼品发放的最小分组数目 - 贪心思维

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布自己的解题思路&#xff0c;希望大家多指教 一、题目描述 又到了一年的末尾&#xff0c;项目组让小明负责为使得参加晚…

八、e2studio VS STM32CubeIDE之内存使用情况窗口

目录 一、概述/目的 二、STM32CubeIDE Build Analyzer 三、e2studio Memory Usage 八、e2studio VS STM32CubeIDE之内存使用情况窗口 一、概述/目的 1、嵌入开发最大特点之一就是资源受限&#xff0c;关注芯片资源使用详情是优秀工程师的技能之一 2、Keil和IAR都不支持内存…

网络库-libcurl介绍

1.简介 libcurl 是一个功能强大的库&#xff0c;支持多种协议&#xff0c;用于数据传输。它广泛应用于实现网络操作&#xff0c;如HTTP、HTTPS、FTP、FTPS、SCP、SFTP等。libcurl 提供了丰富的 API&#xff0c;可以在多种编程语言中使用。 libcurl 主要特点 支持多种协议&am…

CCF-Csp算法能力认证,202209-1如此编码(C++)含解析

前言 推荐书目&#xff0c;在这里推荐那一本《算法笔记》&#xff08;胡明&#xff09;&#xff0c;需要PDF的话&#xff0c;链接如下 「链接&#xff1a;https://pan.xunlei.com/s/VNvz4BUFYqnx8kJ4BI4v1ywPA1?pwd6vdq# 提取码&#xff1a;6vdq”复制这段内容后打开手机迅雷…

MySQL学习3

目录 一.合计/统计函数&#xff1a; 1.合计函数--count&#xff1a; 2.合计函数-sum 3.合计函数-avg 4.合计函数--max/min 二.分组统计&#xff1a; &#xff08;1&#xff09;使用group by子句对列进行分组&#xff1a; &#xff08;2&#xff09;使用having子句对分组…

【网络基础】TCP协议2

TCP建立连接 什么是TCP连接 用于保证可靠性和流量控制维护的某些状态信息&#xff0c;这些信息的组合&#xff0c;包括 Socket、序列号和窗口大小称为连接。 Socket&#xff1a;由 IP 地址和端口号组成 序列号&#xff1a;用来解决乱序问题等 窗口大小&#xff1a;用来做流量…

企业邮箱域名是什么?怎么注册一个企业邮箱域名?

企业邮箱域名是什么&#xff1f;企业邮箱域名是企业申请的专属域名&#xff0c;绑定专属的邮箱域名&#xff0c;能够在发送邮件时提高品牌识别性、专业性和宣传效果。那么&#xff0c;我们该怎么注册一个企业邮箱域名呢&#xff1f;本文将为你详细介绍。 一、企业邮箱域名是什…

揭秘高效引流获客的艺术

在数字营销的海洋中&#xff0c;吸引潜在客户的注意力就像捕捉闪烁的鱼群——需要技巧、耐心和正确的工具。有效的引流获客策略能为企业带来生机&#xff0c;如同春风拂过荒漠&#xff0c;唤醒沉睡的种子。本文将带你领略那些让企业脱颖而出的获客秘籍&#xff0c;让你的目标客…

机器视觉技术精准测量点胶高度与宽度:提升生产质量的新利器

在现代化生产线中&#xff0c;点胶工艺是许多产品制造过程中的重要环节。点胶的高度和宽度直接影响到产品的质量和性能。传统的测量方法往往效率低下、精度不高&#xff0c;而机器视觉技术的引入&#xff0c;为点胶高度和宽度的测量带来了革命性的变革。本文将探讨机器视觉如何…

一文汇总对比英伟达、AMD、英特尔显卡GPU

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f4d1;上期文章&#xff1a;『【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包YOLOv5结合Dobot机械臂实现智能垃圾分类』 &#x1f37b;本文由virobotics(仪酷…