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. pointcut 切面表达式 切入点表达式

    下面给出一些常见切入点表达式的例子. 任意公共方法的执行: execution(public * *(..)) 任何一个以“set”开始的方法的执行: execution(* set*(..)) Ac ...

  2. CentOS上安装配置Ruby on Rails

    0.install sublime editor(optional) ref:http://www.tecmint.com/install-sublime-text-editor-in-linux/ ...

  3. python目录遍历文件名称替换

    # -*- coding:utf-8 -*- import os import os.path import shutil import chardet import codecs mysql_fil ...

  4. vs启动出错(chenlu-1):参数“basePath”不能是相对路径

    参数“basePath”不能是相对路径 原因: 1.调试路径下没有exe文件.没有生成exe文件. 2.项目属性->配置属性->调试->命令中的参数被设置为相对路径.

  5. java课程课后作业04之动手动脑

    一.多层的异常捕获-1 先贴出代码: public class CatchWho { public static void main(String[] args) { try { try { thro ...

  6. TestNG 框架的运用

    TestNG这个测试框架可以很好的和基于Selenium的web自动化测试结合在一起,实现把我们写好的自动化测试用例以自定义顺序执行.下面分为十二步来对TestNG测试框架进行总结,包括环境的部署,从 ...

  7. webstorm安装 利用host破解

    1.官网下载,一路确定(其中最近一版还下载个什么玩意,不要取消,取消后即使安装了也报错找不到jvm的环境变量), 2  打开webstorm,首次使用前accept -->dont sent - ...

  8. js运用2

    1.变量提升 变量提升是浏览器的一个功能,在运行js代码之前,浏览器会给js一个全局作用域叫window,window分两个模块,一个叫内存模块,内存模块找到当前作用域下的所有的带var和functi ...

  9. Linux命令 diff cmp patch

    diff: 以行为单位进行比对 $ cat passwd | sed -e '4d' -e '6c no six line' > passwd.new $ cat -n passwd.new 1 ...

  10. Hibernate 补充 ManyToOne、OneToMany、OneToOne的使用例

    1.前言      Hibernate 为程序员提供一种级联操作,在编写程序时,通过 Hibernate 的级联功能可以很方便的操作数据库的主从表的数据, 我们最常用的级联是级联保存和级联删除.   ...