JAVA 集合之 PriorityQueue

本文介绍了Java集合中的PriorityQueue,它基于堆数据结构实现,提供优先级排序功能。PriorityQueue默认按元素自然顺序排序,可自定义Comparator。文章详细分析了PriorityQueue的构造、成员变量、核心方法如add、peek和remove,并探讨了其在并发场景下的使用。
摘要由CSDN通过智能技术生成

写在开头

​ 本文作为我学习 Java 集合 PriorityQueue 的一个记录与总结,如果文中有纰漏或者错误,请不吝赐教,共同进步!

PriorityQueue

一、PriorityQueue 介绍

1.1 PriorityQueue 概述
  1. PriorityQueue(优先队列) , 其底层的实现是**堆(heap)**这一数据结构
  2. PriorityQueue 维护底层数组长度的方式与 ArrayList 相同
  3. PriorityQueue 中元素默认按照元素的自然顺序排序,也可指定自定义的 Comparator
  4. PriorityQueue 中元素必须是彼此可比的且不能为 null
  5. PriorityQueue 是线程不安全的,在并发场景下应使用 PriorityBlockingQueue
1.2 PriorityQueue 底层数据结构

​ PriorityQueue 底层的数据结构是 堆(heap) , 其一般用数组来作为其实现,但是在逻辑上其更像一棵树,见下图,以数组实现的堆的特点为:设当前元素在数组中的下标为 n 则其左孩子为数组中下标为 [2n+1] 的元素,其右孩子为数组中下标为 [2(n+1)] 的元素。
在这里插入图片描述
在这里插入图片描述

​ 此外,堆的另一个特点是父节点和子节点的关系,特别的对于 PriorityQueue 来说其默认的堆是一个小根堆,其特点为父节点的元素值大于左右俩个子节点,根节点的元素值为整个堆的最小值,其能够在插入或删除时自动维护堆的性质。具体的实现可参考《算法导论》,其中有关于堆的详细介绍,在此就不再继续深入下去了。

二、PriorityQueue 源码分析

2.1 继承类与接口实现
public class PriorityQueue<E> extends AbstractQueue<E>
    implements java.io.Serializable
  • 继承类
    • AbstractQueue:队列的抽象类其实现了 Queue 结构,此类实现了队列的基本功能
  • 接口
    • Serializable 接口:使得 PriorityQueue 可序列化
2.2 成员变量
// PriorityQueue 第一次插入数据时底层数组的大小
private static final int DEFAULT_INITIAL_CAPACITY = 11;
// 底层数组
transient Object[] queue;
// PriorityQueue 的大小
private int size = 0;
// 元素顺序的比较器,若不指定则为 null,即使用元素的自然顺序进行排序
private final Comparator<? super E> comparator;
2.3 构造方法

在这里插入图片描述

​ 看起来很多但基本都是对PriorityQueue(int , Comparator<? super E>) 的不同调用因此,详细介绍一下此构造方法

public PriorityQueue(int initialCapacity,
                     Comparator<? super E> comparator) {
   
	// 保证初始化的数组大小至少为 1
    if (initialCapacity < 1)
        throw new IllegalArgumentException();
    // 初始化底层数组
    this.queue = new Object[initialCapacity];
    // 初始化 PriorityQueue 的比较器为自定义比较器
    this.comparator = comparator;
}

​ 此构造主要做了两件事情,1)初始化底层数组并指定其大小,2)将 PriorityQueue 的比较器指定为用户定义的比较器。此次有一个可有可无的小细节,在此暂且一提,如果阅读过我之前有关 ArrayList 的文章的话会发现,虽然底层都是基于数组,如果不指定具体的初始化长度,那么 PriorityQueue 会在初始化时直接初始化对应长度的数组,而 ArrayList 则会在第一次 add 时才初始化对应长度的数组。

2.4 核心方法

​ PriorityQueue 也是队列因此其核心方法同队列相同即:add(), peek(), remove()

2.4.1 add() 方法
  • add() 方法
public boolean add(E e) {
   
    // 调用了 offer
    return offer(e);
}
  • offer() 方法
public boolean offer(E e) {
   
        if (e == null)
            // PriorityQueue 不允许 null 
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            // 如果 PriorityQueue.size() 超过了底层数组则调用 grow() 方法扩容
            grow(i + 1);
        size = i + 1;
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值