【Queue】- 从源码分析PriorityQueue及其常用方法

news2025/7/12 8:05:36

文章目录

  • PriorityQueue基础知识
    • 概述
    • PriorityQueue内部结构
    • PriorityQueue扩容操作
  • PriorityQueue队列的构造方法
  • PriorityQueue队列的常用方法
    • public boolean offer(E e)
    • public E peek()
    • public boolean remove(Object o)
    • public boolean contains(Object o)
    • public Object[] toArray()
    • public int size()
    • public void clear()
    • public E poll()

PriorityQueue基础知识

概述

PriorityQueue继承至AbstractQueue,并实现了java.io.Serializable接口:

public class PriorityQueue<E> extends AbstractQueue<E>
        implements java.io.Serializable

在这里插入图片描述

PriorityQueue内部结构

PriorityQueue队列为了保证读 / 写性能的平衡,始终维持着一个堆结构,它保证了在每次添加新数据对象、移除已有数据对象后,集合都能维持小顶堆的特点。也就是说,PriorityQueue队列每进行一次写操作,都会针对集合中新的数据情况进行调整,保证部集合中所有数据对象始终按照小顶堆或大顶堆的结构特点进行排序。

PriorityQueue队列内部使用一个数组变量queue存储数据对象:

/**
     * Priority queue represented as a balanced binary heap: the two
     * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
     * priority queue is ordered by comparator, or by the elements'
     * natural ordering, if comparator is null: For each node n in the
     * heap and each descendant d of n, n <= d.  The element with the
     * lowest value is in queue[0], assuming the queue is nonempty.
     */
    transient Object[] queue; // non-private to simplify nested class access

PriorityQueue扩容操作

PriorityQueue队列的默认初始容量大小为11:

private static final int DEFAULT_INITIAL_CAPACITY = 11;

当数组容量达到上限时,需要进行扩容操作。

扩容操作实现如下:

    private void grow(int minCapacity) {
        int oldCapacity = queue.length;
        // Double size if small; else grow by 50%
        int newCapacity = oldCapacity + ((oldCapacity < 64) ?
                (oldCapacity + 2) :
                (oldCapacity >> 1));
        // overflow-conscious code
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        queue = Arrays.copyOf(queue, newCapacity);
    }

当PriorityQueue队列的原始容量值小于64时,进行双倍扩容;原始容量值大于64时,进行50%扩容。

最大允许分配容量为:

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

PriorityQueue队列的构造方法

1. 创建一个初始容量为11的PriorityQueue队列

    public PriorityQueue() {
        this(DEFAULT_INITIAL_CAPACITY, null);
    }

2. 创建一个具有指定初始容量的PriorityQueue

public PriorityQueue(int initialCapacity) {
        this(initialCapacity, null);
    }

3. 构造一个包含指定集合元素的PriorityQueue

    public PriorityQueue(Collection<? extends E> c) {
        if (c instanceof SortedSet<?>) {
            SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
            this.comparator = (Comparator<? super E>) ss.comparator();
            initElementsFromCollection(ss);
        } else if (c instanceof PriorityQueue<?>) {
            PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
            this.comparator = (Comparator<? super E>) pq.comparator();
            initFromPriorityQueue(pq);
        } else {
            this.comparator = null;
            initFromCollection(c);
        }
    }

4. 创建包含 PriorityQueue队列中的元素的PriorityQueue

    public PriorityQueue(PriorityQueue<? extends E> c) {
        this.comparator = (Comparator<? super E>) c.comparator();
        initFromPriorityQueue(c);
    }

5. 创建默认初始容量为DEFAULT_INITIAL_CAPACITY的 PriorityQueue ,并根据指定的比较器对其元素进行排序

    public PriorityQueue(Comparator<? super E> comparator) {
        this(DEFAULT_INITIAL_CAPACITY, comparator);
    }

6. 创建具有默认初始容量的 PriorityQueue ,并根据指定的比较器对其元素进行排序

    public PriorityQueue(int initialCapacity,
                         Comparator<? super E> comparator) {
        // Note: This restriction of at least one is not actually needed,
        // but continues for 1.5 compatibility
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.queue = new Object[initialCapacity];
        this.comparator = comparator;
    }

PriorityQueue队列的常用方法

public boolean offer(E e)

将指定的元素插入到此PriorityQueue队列中。

    public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            grow(i + 1);
        size = i + 1;
        if (i == 0)
            queue[0] = e;
        else
            siftUp(i, e);
        return true;
    }

public E peek()

检索但不删除此队列的头部,如果此队列为空,则返回 null 。

    public E peek() {
        return (size == 0) ? null : (E) queue[0];
    }

public boolean remove(Object o)

删除指定对象元素,删除成功返回true。

    public boolean remove(Object o) {
        int i = indexOf(o);
        if (i == -1)
            return false;
        else {
            removeAt(i);
            return true;
        }
    }

public boolean contains(Object o)

如果此队列包含指定的元素,则返回true 。

public boolean contains(Object o) {
        return indexOf(o) != -1;
    }

public Object[] toArray()

返回一个包含此队列中所有元素的数组。

    public Object[] toArray() {
        return Arrays.copyOf(queue, size);
    }

public int size()

返回此集合中的元素数。

    public int size() {
        return size;
    }

public void clear()

清空

    public void clear() {
        modCount++;
        for (int i = 0; i < size; i++)
            queue[i] = null;
        size = 0;
    }

public E poll()

检索并删除此队列的头,如果此队列为空,则返回 null 。

    public E poll() {
        if (size == 0)
            return null;
        int s = --size;
        modCount++;
        E result = (E) queue[0];
        E x = (E) queue[s];
        queue[s] = null;
        if (s != 0)
            siftDown(0, x);
        return result;
    }

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

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

相关文章

【SU-03T离线语音模块】:学习配置使用

前言 时不可以苟遇&#xff0c;道不可以虚行。 一、介绍 1、什么是语音识别模块 语音识别模块是在一种基于嵌入式的语音识别技术的模块&#xff0c;主要包括语音识别芯片和一些其他的附属电路&#xff0c;能够方便的与主控芯片进行通讯&#xff0c;开发者可以方便的将该模块嵌…

Node.js 入门教程 3 如何安装 Node.js

Node.js 入门教程 Node.js官方入门教程 Node.js中文网 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录Node.js 入门教程3 如何安装 Node.js3 如何安装 Node.js Node.js 可以通过多种方式安装。 所有主流平台的官方软件包都可以在 http://node…

终于见识到了微服务的天花板:阿里内部SpringCloud全线手册,太强了

后台都是在问微服务架构的面试题怎么答&#xff0c;想聊聊微服务架构了。微服务架构一跃成为 IT 领域炙手可热的话题也就这两年的事&#xff0c;大量一线互联网公司因为庞大的业务体量和业务需求&#xff0c;纷纷投入了微服务架构的建设中&#xff0c;像阿里巴巴、百度、美团等…

226. 翻转二叉树

文章目录1.题目2.示例3.答案①递归②迭代1.题目 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 2.示例 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xf…

智慧应急解决方案-最新全套文件

智慧应急解决方案-最新全套文件一、建设背景二、建设思路应急管理信息化发展“四纵四横”总体架构1、两网络2、四体系3、两机制三、建设方案四、获取 - 智慧应急全套最新解决方案合集一、建设背景 建立应急大数据管理体系是应急管理信息化建设中的重要环节&#xff0c;决定了应…

将数组沿指定轴划分为子数组numpy.split()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将数组沿指定轴划分为子数组 numpy.split() [太阳]选择题 以下python代码输出错误的一项是? import numpy as np xnp.array([1,2,3,4,5,6,7,8,9,10,11,12]) print(【显示】x&#x…

数据库安装记录——Mysql8.0.23 msi 保姆级安装教程

今天遇到现场服务器安装数据库&#xff0c;特意记录安装过程。 本篇记录的服务器系统为&#xff1a;Windows Server 2012 R2 Standard 数据库版本为&#xff1a;Mysql8.0.23 msi 1、官网下载相应版本 2、安装过程 开端不顺&#xff0c;开始就出弹窗&#xff1a; 先插入一…

下载神器-IDM使用教程及下载

软件介绍&#xff1a; IDM是“Internet Download Manager”的简称&#xff0c;意思是“互联网下载管理器”&#xff0c;既是一类软件的统称&#xff0c;也专指一个非常知名的互联网下载器&#xff0c;这个软件的名字就叫IDM&#xff0c;被誉为地表最强下载器&#xff0c;屌丝救…

Flutter 中使用 extension 使项目更具可读性和效率 01

Flutter 中使用 extension 使项目更具可读性和效率 01 原文 https://medium.com/bedirhanssaglam/make-your-flutter-projects-more-readable-and-effective-with-extensions-b7dffd32e2f4 前言 代码的可读性和实用性在《 Flutter 》中非常重要。今天我们将编写一些 extension …

代码行覆盖率学习

【强力推荐】jacoco代码测试覆盖率实战教学全集&#xff0c;7天从入门到精通【理论实战 赶紧拿走】_哔哩哔哩_bilibili on-the-fly: 测试的时候代码是动态的, 需要测试就帮你插桩, 不测就不帮你插桩 offline: 先把被测代码拿到一次性直接插桩, 一运行桩就已经插好了, 直接生成…

如何把一个视频分割成不同时长的多个小视频

大家平时找素材是不是有点困难&#xff0c;如何把一个视频一个分割成多个不同时长的小视频呢&#xff0c;分割视频时能不能按我们需要来分割&#xff0c;今天小编带大伙来了解决下分割视频操作方法和步骤。 先来看下原来视频&#xff0c;原视频时长是比较长的 接下来我们准备一…

掌握这些 Spring Boot 启动扩展点,已经超过 90% 的人了!

1.背景 Spring的核心思想就是容器&#xff0c;当容器refresh的时候&#xff0c;外部看上去风平浪静&#xff0c;其实内部则是一片惊涛骇浪&#xff0c;汪洋一片。Springboot更是封装了Spring&#xff0c;遵循约定大于配置&#xff0c;加上自动装配的机制。很多时候我们只要引用…

Docker - Docker部署war包

使用Docker部署war项目&#xff0c;必须要用容器&#xff0c;我们就用tomcact容器&#xff0c;其实都是将war包丢到tomcat的webapps目录下&#xff0c;tomcat启动的情况下会自动解压war包 部署war包有两种方式 1、在Docker中安装tomcat容器的镜像&#xff0c;然后把war包丢到…

【无人机】模拟一群配备向下摄像头的移动空中代理覆盖平面区域(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

极速Go语言入门(超全超详细)-基础篇2

文章目录函数进阶结构体接口继承type值类型与引用类型值传递、引用传递打包、引用包工具类打包文件代码引用包代码方法异常捕捉处理字符串常用函数日期常用函数管道(channel)书接上篇&#xff1a;极速Go语言入门(超全超详细)-基础篇 整个基础篇合计32000字左右,如有遗漏可以私…

RDD—Transformation算子

Spark核心编程&#xff08;Spark Core&#xff09; 文章目录Spark核心编程&#xff08;Spark Core&#xff09;1. 了解RDD1.2 RDD五大特性1.3 WordCount案例分析2 RDD编程入门2.1 RDD的创建2.2 RDD算子2.3 常用Transformation 算子小案例&#xff08;客户端&#xff0c;集群&am…

Flutter高仿微信-第45篇-群聊-文本

Flutter高仿微信系列共59篇&#xff0c;从Flutter客户端、Kotlin客户端、Web服务器、数据库表结构、Xmpp即时通讯服务器、视频通话服务器、腾讯云服务器全面讲解。 详情请查看 效果图&#xff1a; 实现代码&#xff1a; 详情请参考Flutter高仿微信-第44篇-群聊&#xff0c; 这里…

Win10更新后卡在输入密码的界面

注意&#xff1a; 系统没问题时候建议创建还原点&#xff0c;以防万一&#xff1a; 创建还原点方法&#xff1a; 设置-系统-关于-系统保护-创建还原点。 下面介绍Win10更新后卡在输入密码的界面解决方法。 此时进不去系统&#xff0c;想进行还原点还原。 首先需要进入疑难解答…

安全分析能力的核心能力

核心能力 为了加快安全分析能力更全面、更深入的自动化 &#xff0c;SecXOps 的目标在于创建一个集成的用于 Security 的 XOps 实践&#xff0c;提升安全分析的场景覆盖率和运营效率。SecXOps 技术并不 015 SecXOps 技术体系 是 Ops 技术在安全领域的简单加和&#xff0c;SecXO…

第二章:线程基础知识复习

为什么要学好多线程如此重要? 硬件方面 摩尔定律 它是由英特尔创始人之一-Gordon Moore(戈登●摩尔)提出来的。其内容为: . 当价格不变时&#xff0c;集成电路上可容纳的元器件的数目约每隔18-24个月便会增加一倍&#xff0c;性能也将提升一倍。换言之&#xff0c;每一美元所…