源码分析-PriorityQueue

本文深入分析了PriorityQueue的数据结构和实现原理,包括二叉堆特性、初始化过程、下滤(siftDown)和上移(siftUp)操作的细节。此外,还探讨了PriorityQueue的删除操作及其对迭代器的影响,特别是如何确保迭代器能遍历所有元素,即使在元素变动的情况下。
摘要由CSDN通过智能技术生成

PriorityQueue实现的方式和数据结构中二叉堆的基本实现是一致。也就是内置了一个数组,将这个数组视为一个树,这棵树有这样的一些特性:

  • 对应任意节点i ,其左子节点为(2*i+1),右节点为2*(i+1);
  • 数组的前半部分必为非叶节点。

内置了siftUp和siftDown两种私有访问的方法用于进行下滤和上移操作。其次还有需要注意的是对指定comparator的应用。其他的部分比较常规。

初始化

这里写图片描述
如上图所示,C表示构造函数,绿色表示public访问,红色表示private访问,灰色是辅助标注。
一般来说初始化包括两大类,一类是非集合参数的初始化。

非集合类:
最终调用的都是PriorityQueue(int i,Comparator < ? extends E >)。默认参数分别是11和null;

集合类:
集合类的调用构造器对结果进行了分类,最终都会使用3中方式完成初始化。这里主要来看下这三种方式:

  • initElementsFromCollection
    private void initElementsFromCollection(Collection<? extends E> c) {
        Object[] a = c.toArray();
        // If c.toArray incorrectly doesn't return Object[], copy it.
        if (a.getClass() != Object[].class)
            a = Arrays.copyOf(a, a.length, Object[].class);
        int len = a.length;
        if (len == 1 || this.comparator != null)
            for (int i = 0; i < len; i++)
                if (a[i] == null)
                    throw new NullPointerException();
        this.queue = a;
        this.size = a.length;
    }

这个类新建了一个Object[]类型的数组,将内部的queue指向这个新建的Object数组。这里不太明白的是既然是检测元素是否为非0 为何要在if (len == 1 || this.comparator != null这样的情况下检测。而不是所有情况下都检测。首先comparator!=null。比较好理解一些,因为如果是null的话那后续调用null.comparator必然会出现问题。但是len==1就不是很明白了。

在输入序列是一个sortSet的情况下。只需要将其数组直接赋值过来就行。其实这个比较好理解。因为堆自身实际上并不是全排序的而是偏序的,而一个排序的集合生成的数组必然满足堆的内置数组的排序要求。或者说全排序的数组是堆的数组的一种特殊情况。因此直接复制就可以了。

  • initFromCollection
    private 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值