public boolean hasNext() {
return cursor < size ||
(forgetMeNot != null && !forgetMeNot.isEmpty());
} //内部的迭代器,就是数组的迭代,迭代指针cursor,
public E next() {
if (expectedModCount != modCount)
throw new ConcurrentModificationException();
if (cursor < size)
return (E) queue[lastRet = cursor++];
if (forgetMeNot != null) {
lastRet = -1;
lastRetElt = forgetMeNot.poll();
if (lastRetElt != null)
return lastRetElt;
}
throw new NoSuchElementException();
}

扩容:
private void grow(int minCapacity) {
int oldCapacity = queue.length;
// 小于64扩大为原来2倍,大于等于64扩大为原来1.5倍,
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);//丢弃原来的数组,指向新的数组,
}
public class zusheQueue {
private static PriorityQueue<Integer> queue = new PriorityQueue<Integer>(3); public static void main(String[] args) {
queue.offer(80);
queue.offer(60);
queue.offer(70);
queue.offer(40);
queue.offer(20);
queue.offer(10);
queue.offer(90);
queue.offer(22);
queue.offer(15);
queue.offer(4);
queue.offer(1);
System.out.println(queue);//[1, 4, 20, 22, 10, 70, 90, 80, 40, 60, 15] 数组实现最小堆
System.out.println("出来 "+queue.poll());
System.out.println("出来 "+queue.poll());
System.out.println("出来 "+queue.poll());
System.out.println("出来 "+queue.poll());
/*出来 1
出来 4
出来 10
出来 15 出来最小的*/
System.out.println(queue); Iterator i = queue.iterator();
while(i.hasNext()) {
System.out.print(i.next() + " ");//1 4 20 22 10 70 90 80 40 60 15
} List<Integer> l = Arrays.asList(7,85,4,9,5,85,74,5,8);
PriorityQueue<Integer> p = new PriorityQueue<>(l);
System.out.println(p);
} }

private void siftUpComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>) x;
while (k > 0) {
int parent = (k - 1) >>> 1; //无符号右移
Object e = queue[parent];
if (key.compareTo((E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = key;
}

private void siftDownComparable(int k, E x) { // k = 0
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1; // 非叶子节点
while (k < half) {
int child = (k << 1) + 1; // child = 左孩子
Object c = queue[child]; // c = 左孩子
int right = child + 1;//right = 右孩子
if (right < size &&
((Comparable<? super E>) c).compareTo((E) queue[right]) > 0) //有右孩子,并且左孩子大于右孩子
c = queue[child = right];// c = 右孩子,child = 右孩子
if (key.compareTo((E) c) <= 0) //key小于右孩子,就是小于所有孩子
break; //结束循环
queue[k] = c; // 否则key大于右孩子,k位置是右孩子,就是较小的孩子
k = child; //指针k值为right右孩子的位置, 比较都是根据指针位置比较,放的时候才放对象。
}
queue[k] = key;
}

构造函数:

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);
}
}
private void initFromCollection(Collection<? extends E> c) {
initElementsFromCollection(c);
heapify();
}
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;
}
private void heapify() {
for (int i = (size >>> 1) - 1; i >= 0; i--) //(size >>> 1) - 1就是找到第一个非叶子节点,然后从下到上从右到左,
siftDown(i, (E) queue[i]);
}

public E poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0]; //取出第0个元素
E x = (E) queue[s]; //取出最后一个元素
queue[s] = null; // 最后一个元素置为空
if (s != 0)
siftDown(0, x); // 最后一个元素不要先不要放在第0个元素位置,比较之后确定位置了再放。放置的都是左右孩子,改变的是k的值,key不到最后不放。
return result; //返回第0个元素
}
private void siftDownComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1;
while (k < half) {
// sI, sV是左右子节点的较小位置和值,k,key是要比较的元素和准备放的位置(落之前要比较在放)
int sI = (k << 1) + 1; // 较小位置=左孩子索引
Object sV = queue[sI];//较小值=左孩子
int right = sI+ 1;
if (right < size &&
((Comparable<? super E>) sV ).compareTo((E) queue[right]) > 0) //有右孩子,并且左孩子大于右孩子,
sV = queue[sI= right]; // 较小位置=右孩子索引,较小值=右孩子,
if (key.compareTo((E) sV ) <= 0) //key比左右都小,放上去,
break;
queue[k] = sV ;//否则key比子节点要大,交换位置,并且自己准备放在sl的位置。放置的都是左右孩子,改变的是k的值,key不到最后不放。
k = sI; //自己放在sl的位置之前,也要跟子节点比较一下,在放。
}
queue[k] = key;//key放在k的位置
}

PriorityQueue 源码分析的更多相关文章

  1. 死磕 java集合之PriorityQueue源码分析

    问题 (1)什么是优先级队列? (2)怎么实现一个优先级队列? (3)PriorityQueue是线程安全的吗? (4)PriorityQueue就有序的吗? 简介 优先级队列,是0个或多个元素的集合 ...

  2. PriorityQueue源码分析

          PriorityQueue其实是一个优先队列,和先进先出(FIFO)的队列的区别在于,优先队列每次出队的元素都是优先级最高的元素.那么怎么确定哪一个元素的优先级最高呢,jdk中使用堆这么一 ...

  3. 死磕 java集合之DelayQueue源码分析

    问题 (1)DelayQueue是阻塞队列吗? (2)DelayQueue的实现方式? (3)DelayQueue主要用于什么场景? 简介 DelayQueue是java并发包下的延时阻塞队列,常用于 ...

  4. 死磕 java集合之PriorityBlockingQueue源码分析

    问题 (1)PriorityBlockingQueue的实现方式? (2)PriorityBlockingQueue是否需要扩容? (3)PriorityBlockingQueue是怎么控制并发安全的 ...

  5. java读源码 之 queue源码分析(PriorityQueue,附图)

    今天要介绍的是基础容器类(为了与并发容器类区分开来而命名的名字)中的另一个成员--PriorityQueue,它的大名叫做优先级队列,想必即使没有用过也该有所耳闻吧,什么?没..没听过?emmm... ...

  6. 介绍开源的.net通信框架NetworkComms框架 源码分析

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了 ...

  7. Mahout源码分析:并行化FP-Growth算法

    FP-Growth是一种常被用来进行关联分析,挖掘频繁项的算法.与Aprior算法相比,FP-Growth算法采用前缀树的形式来表征数据,减少了扫描事务数据库的次数,通过递归地生成条件FP-tree来 ...

  8. 细说并发5:Java 阻塞队列源码分析(下)

    上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...

  9. HDFS源码分析EditLog之获取编辑日志输入流

    在<HDFS源码分析之EditLogTailer>一文中,我们详细了解了编辑日志跟踪器EditLogTailer的实现,介绍了其内部编辑日志追踪线程EditLogTailerThread的 ...

随机推荐

  1. count(1)、count(*)与count(列名)的执行区别

    执行效果: 1.  count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了! 从执行计划来看,count(1)和coun ...

  2. maven jdk 版本配置

    一种是配置 pom.xml,一种是配置 settings.xml. 方式一:settings.xml 配置 打开 %maven%/conf/settings.xml 文件并编辑它(%maven% 表示 ...

  3. Thread类的join()方法

    public class Demo { /** * Thread类的join()方法 * -------------------------------- * 1)join() * 2)join(lo ...

  4. Android基础开发归档

    一.Android 基本组件汇总 1. Android中PackageManager使用示例 :  http://blog.csdn.net/qinjuning/article/details/686 ...

  5. Git忽略已经被版本控制的文件(添加.gitignore不会起作用)

    说明:已经被维护起来的文件(需要被远程仓库控制),即使加入.gitignore也会无济于事. .gitignore只对那些只存在在本地,而不在远程仓库的文件起作用.(untraked file). 操 ...

  6. HTML中include file的用法

    语法 <!-- #include PathType = "FileName" --> 参数 PathType  路径类型 路径可为以下某种类型: 文件 该文件名是带有  ...

  7. 微信企业号-根据code获取成员信息(过期code)

    二次请求获取成员信息时,会报如下错误: { "errcode": "40029", "errmsg": "invalid code ...

  8. Yarn Node Labels

    Yarn Node Labels + Capacity-Scheduler 在yarn-site.xml中开启capacity-schedule yarn-site.xml <property& ...

  9. 黑盒测试实践——day01

    一.任务进展情况 小组成员讨论了测试案例的选取以及测试工具的选取,目前正在设计合理的测试方法,研究待测试系统的功能需求和缺陷. 二.存在的问题 测试工具的使用还是不很清楚. 三.解决方法 通过上网搜集 ...

  10. Luogu 1068 - 分数线划定 - [快速排序]

    题目链接:https://www.luogu.org/problemnew/show/P1068 题目描述世博会志愿者的选拔工作正在 A 市如火如荼的进行.为了选拔最合适的人才,A 市对所有报名的选手 ...