PriorityQueue初始化和方法

2023-09-20 10:40:34

PriorityQueue概述

PriorityQueue` 是 Java 中的一个数据结构,它是一个优先队列实现,可以用来存储一组元素,并根据其优先级进行排序和检索。优先队列是一种特殊的队列,其中元素被赋予了优先级,高优先级的元素在队列中排在低优先级元素的前面。

以下是 PriorityQueue 的一些重要特性和用法:

  1. 基本特性

    • PriorityQueue 是一个基于堆(heap)数据结构实现的,通常是一个最小堆(Min Heap),也可以通过传递比较器来创建最大堆(Max Heap)。
    • 元素根据其优先级自动排序,高优先级的元素在队列前面。
  2. 元素插入

    • 使用 add()offer() 方法将元素插入队列中。
  3. 元素获取

    • 使用 peek() 方法可以获取队列中优先级最高的元素,但不删除它。
    • 使用 poll() 方法可以获取并移除队列中优先级最高的元素。
  4. 遍历元素

    • PriorityQueue 并没有提供迭代器来遍历元素,因为它并不保证元素的顺序。
  5. 自定义优先级

    • 可以通过为构造函数传递自定义的 Comparator 对象来定义元素的优先级比较规则。如果不提供比较器,元素必须实现 Comparable 接口来自然排序。
  6. 线程安全性

    • PriorityQueue 不是线程安全的,如果多个线程同时访问一个 PriorityQueue 实例,需要进行外部同步处理。
  7. 应用场景

    • PriorityQueue 常用于一些需要按优先级处理任务的场景,如任务调度器、最短路径算法(如Dijkstra算法)等。

以下是一个示例,演示了如何创建和使用 PriorityQueue

import java.util.PriorityQueue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        // 创建一个最小堆的PriorityQueue
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        
        // 插入元素
        minHeap.add(5);
        minHeap.add(2);
        minHeap.add(8);
        
        // 获取并移除最小元素
        int smallest = minHeap.poll(); // 结果:2
        System.out.println("Smallest element: " + smallest);
        
        // 获取但不移除最小元素
        int smallestPeek = minHeap.peek(); // 结果:5
        System.out.println("Smallest element (peek): " + smallestPeek);
    }
}

使用比较器构造最大堆

PriorityQueue<ListNode> q = new PriorityQueue<>(lists.length, (a, b) -> a.val - b.val);

这里使用<>来指定元素类型,确保a和b能够正确地识别为ListNode类型,从而访问val属性。
需要注意初始容量不能是0,加入的元素也不能是null

// 使用 Lambda 表达式创建最大堆比较器
Comparator maxHeapComparator = (a, b) -> b - a;
PriorityQueue maxHeap = new PriorityQueue<>(maxHeapComparator);
Comparator 是一个函数式接口,它只包含一个抽象方法 compare(T o1, T o2),这个方法接受两个参数并返回一个整数,用于比较这两个对象的大小。由于 Comparator 是函数式接口,因此可以使用 Lambda 表达式来创建它的实例。

在上述代码中,(a, b) -> b.val - a.val 是一个 Lambda 表达式,它实际上是一个匿名函数,等价于以下的 compare 方法:

int compare(ListNode a, ListNode b) {
    return b.val - a.val;
}

Lambda 表达式的左侧 (a, b) 是参数列表,右侧 b.val - a.val 是函数体,表示通过比较 b.vala.val 的差值来确定两个对象的顺序。这个差值为正时,表示 ba 大,为负时,表示 ab 大,为零时,表示它们相等。

因此,Lambda 表达式 (a, b) -> b.val - a.val 是创建了一个比较器,用于按照 ListNode 对象的 val 属性从大到小排序。这个比较器可以传递给 PriorityQueue,以确保最大的节点在堆的顶部。Lambda 表达式的简洁性使得它成为创建匿名函数对象的一种便捷方式。

扩容机制

在 PriorityQueue 中,动态扩容是在插入元素时进行的。以下是动态扩容的一般细节:

初始化:创建一个初始容量(默认是11)的数组,并将第一个元素插入其中。

插入元素:当插入一个新元素时,首先将其添加到数组的末尾。然后,它会根据堆的性质,比较新元素和其父节点的值。如果满足堆的性质,操作结束。如果不满足,就将新元素和父节点交换位置,然后继续比较新元素和新的父节点,直到满足堆的性质为止。

数组扩容:如果在插入元素时发现数组已满,就需要进行扩容。扩容通常会创建一个更大的新数组,然后将所有元素从旧数组复制到新数组中。

扩容策略:通常情况下,扩容的策略是将数组的容量翻倍,以减少频繁扩容的次数。这样可以保持在插入大量元素时的高效性能。

需要注意的是,虽然 PriorityQueue 具有动态扩容的机制,但扩容操作的代价相对较高,因为需要复制数组的所有元素。因此,在处理大量数据时,建议初始化 PriorityQueue 时指定一个足够大的初始容量,以减少扩容的次数,提高性能。

更多推荐

《TCP/IP网络编程》阅读笔记--多线程服务器端的实现

目录1--多线程的优点2--进程和线程的差异3--线程创建4--线程使用5--线程安全问题6--互斥量7--信号量8--线程销毁9--多线程并发聊天程序9-1--服务器端9-2--客户端9-3--测试结果1--多线程的优点多进程服务器的缺点:①创建进程的过程会带来一定的开销;②为了完成进程间的数据交换,需要特殊的IPC

数据分析三剑客之Numpy

数据分析三剑客:Numpy,Pandas,Matplotlib1.简介NumPy(NumericalPython)是Python语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。numpy是基于c语言开发,所以这使得numpy的运行速度很快,高效率运行就是numpy的一大优势。

认识数据分析

文章目录1.认识数据分析1.1数据自身的三大属性1.2建数仓数据分析的工程技术1.3数据分析解决问题的原理1.4数据分析的具体流程1.5数据的中心化和智能化1.6数据分析的四种类型和六个方向1.认识数据分析1.1数据自身的三大属性客观:用数字衡量和表现一件客观事物时,能最大程度统一大家的认知量化:量化的数据,可以利用数

SELinux

简介SELinux:SecurityEnhancedLinux,安全强化Linux自主访问控制DAC这是传统文件权限与账号关系,依据进程的拥有者与文件资源的rwx权限来决定有无存取的能力。缺点:root具有最高权限如果不小心某个进程被有心人取得,且该进程属于root权限,那么这支进程就可以在系统上进行任何资源的存取。使

基于Java酒店预约及管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

Linux网络编程:使用UDP和TCP协议实现网络通信

目录一.端口号的概念二.对于UDP和TCP协议的认识三.网络字节序3.1字节序的概念3.2网络通信中的字节序3.3本地地址格式和网络地址格式四.socket编程的常用函数4.1sockaddr结构体4.2socket编程常见函数的功能和使用方法五.UDP协议实现网络通信5.1UDP协议服务端的封装5.2UDP协议客户端

Rust结构体和枚举

结构体struct,或者structure,是一个自定义数据类型,允许你包装和命名多个相关的值,从而形成一个有意义的组合。声明定义结构体,需要使用struct关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为字段(field)。struc

网安之PHP基础作业(5)

目录目录前言系列文章列表IJ中PHP环境的搭建和使用教程思维导图1,简答题1.1.题目部分1.2,题目分析2,页面一实现2.1,题解2.2,页面效果展示3,页面二的实现3.1,题解3.2,题目结果展示3.2.1,结果13.2.2,结果23.2.3,结果34,总结前言本博文,主要是对自己在学校PHP基础第5节课后,对作业

[maven] maven 创建 web 项目并嵌套项目

[maven]maven创建web项目并嵌套项目这里主要就创建另外一个web项目,并且创建一个parent项目比较方便的管理一下两个子项目。mavenweb项目web创建和quickstart的过程是差不多的,只不过这里换乘webapp,配置方便的话可以搞的东西挺多的……这里就搞servlet,上古版本的东西了。cre

如何利用Requestly提升前端开发与测试的效率

【软件测试行业现状】2023年了你还敢学软件测试?未来已寄..测试人该何去何从?【自动化测试、测试开发、性能测试】前端测试在进行前端页面开发或者测试的时候,我们会遇到这一类场景:在开发阶段,前端想通过调用真实的接口返回响应在开发或者生产阶段需要验证前端页面的一些异常场景或者临界值时在测试阶段,想直接通过修改接口响应来验

14:00面试,14:06就出来了,问的问题有点变态。。。

从小厂出来,没想到在另一家公司又寄了。到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到5月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%,这下搞的饭都吃不起了。还在有个朋友内推我去了一家互联网公司,兴冲冲见面试官,没想到一道题把我给问死了:如果模块请求http改为了h

热文推荐