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) {// 创建一个PriorityQueuePriorityQueue<Integer> pq = new PriorityQueue<>();// 添加元素pq.offer(1);pq.offer(3);pq.offer(2);// 获取元素System.out.println(pq.poll()); // 1System.out.println(pq.poll()); // 2System.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 !!!


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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C++核心编程-09]----C++类和对象之继承

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

探究NVMe SSD HMB应用场景与影响-<续>

如果需要采用HMB功能&#xff0c;需要SSD支持NVME协议且NVMe 1.2及以上版本。NVME协议中对HMB对应有2个关键参数&#xff1a; HMB建议值&#xff08;HMPRE&#xff09;&#xff1a;设定实际分配给HMB使用的主机内存容量&#xff0c;为设备提供最优性能的内存分配量。 HMB最小值…

Offer必备算法38_贪心算法四_八道力扣题详解(由易到难)

目录 ①力扣56. 合并区间 解析代码 ②力扣435. 无重叠区间 解析代码 ③力扣452. 用最少数量的箭引爆气球 解析代码 ④力扣397. 整数替换 解析代码1_递归改记忆化搜索 解析代码2_贪心策略 ⑤力扣354. 俄罗斯套娃信封问题 解析代码1_动态规划&#xff08;超时&#xf…

盛最多水的容器(双指针)

解题思路&#xff1a; 1&#xff0c;暴力解法&#xff08;超时&#xff09; 我们可以使用两层for循环进行遍历。找到那个最大的面积即可&#xff0c;这里我就不写代码了&#xff0c;因为写了也是超时。 2&#xff0c;双指针法 先定义两个指针一个在最左端&#xff0c;一个在…

C++入门-stack和queue(下)

大家好啊&#xff0c;在这先祝天下的母亲节日快乐啦&#xff01;现在呢&#xff0c;给大家带来C中priority_queue和容器适配器的相关知识点 3.1 C 中的优先队列&#xff08;priority_queue&#xff09;介绍 优先队列&#xff08;priority_queue&#xff09;是一种特殊的队列…

(三)小程序样式和组件

视频链接&#xff1a;尚硅谷2024最新版微信小程序 文章目录 小程序的样式和组件介绍样式-尺寸单位 rpx样式-全局样式和局部样式组件-组件案例演示组件案例-轮播图区域绘制组件案例-轮播图图片添加组件案例-绘制公司信息区域组件案例-商品导航区域组件案例-跳转到商品列表组件案…

使用Vue3开发项目,搭建Vue cli3项目步骤

1.打开cmd &#xff0c;输入 vue create neoai遇到这样的问题 则需要升级一下电脑上 Vue Cli版本哈 升级完成之后 再次输入命令&#xff0c;创建vue3项目 vue create neoai安装完成后&#xff0c;输入 npm run serve 就可以运行项目啦~ 页面运行效果

基于微信小程序+JAVA Springboot 实现的【马拉松报名系统】app+后台管理系统 (内附设计LW + PPT+ 源码+ 演示视频 下载)

项目名称 项目名称&#xff1a; 马拉松报名系统微信小程序 项目技术栈 该项目采用了以下核心技术栈&#xff1a; 后端框架/库&#xff1a; Java SSM框架数据库&#xff1a; MySQL前端技术&#xff1a; 微信开发者工具、uni-app其他技术&#xff1a; JSP开发技术 项目展示 …

绝地求生PUBG初版艾伦格回归 初版艾伦格和新版有什么区别

PUBG终于迎来了经典的旧版艾伦格地图的回归&#xff01;我们希望通过本次经典艾伦格的回归为大家带回记忆中那一幕幕熟悉的场景&#xff0c;并让大家好好回味一番当年与好友们共同冒险的峥嵘岁月&#xff01;还怀念从前为了抢到自己最爱的武器而飞奔的日日夜夜吗&#xff1f;那…

InstantStyle —— 文本到图像生成中的风格保持新突破

在人工智能领域&#xff0c;文本到图像生成&#xff08;Text-to-Image Generation&#xff09;技术正迅速发展&#xff0c;其应用范围从娱乐到专业设计不断扩展。然而&#xff0c;风格一致性生成一直是该领域的一个技术难题。最近&#xff0c;InstantX团队提出了一种名为Instan…

MyBatis——模拟MyBatis框架

一、dom4j 解析 XML 文件 在 dom4j 中&#xff0c;DOMReader 和 SAXReader 是两种不同的 XML 解析器。 它们的主要区别在于解析 XML 的方式和所提供的功能&#xff1a; DOMReader&#xff1a; DOMReader 使用 DOM&#xff08;Document Object Model&#xff09;模型来表示整个…

国内使用 CloudFlare 避坑指南

最近明月收到了不少新手使用 CloudFlare 的求助,发现很多首次使用 CloudFlare 的甚至包括已经在使用 CloudFlare 的站长们对 CloudFlare 的使用有很多的误区,再加上国内简中互联网上有关 CloudFlare 的教程良莠不齐,更是加深了新手使用 CloudFlare 入坑的概率,让一些别有用…