Lucene PriorityQueue & JDK PriorityQueue
麻蛋,原来是最小堆呀! 数据结构不熟害死人呀! 看来待复习复习数据结构了
在lucene源码中对多个段合并的时候,会先将多个段放到一个PriorityQueue中,不要被这个名字迷惑,这个PriorityQueue和JDK的PriorityQueue是完全两个类,而且底层实现也完全不一样,lucene的队列并不是数据结构里学的先进先出的结构,lucene的这个PriorityQueue(org.apache.lucene.util.PriorityQueue)只满足部分有序,为什么要这样设计? 可能是为了性能。那哪部分有序? 这个需要了解基础的操作put和pop的实现,PriorityQueue底层也是一个Object数组,对该队列的操作主要是两个:
PUT:
put操作就是往队列里新增一个元素,当put时候是把新增的元素放到Object数字的最后一个位置上,在PriorityQueue中有个size变量用于存储当前Object数字存储的真实元素有多少个,每次put时候就是把size++然后存到size的位置上,存完以后内部会再执行一个upHeap的操作,这个操作就是将新增的这个元素调整到合适的位置,为什么叫upHeap,是因为新增的元素在数组的最后一个位置上,调整的方向是从后往前,找到这个新增的元素大小合适的地方,排序的规则是由lessThan方法决定,这个由使用PriorityQueue的地方实现该方法。具体的找的逻辑类似二分查找,每次都查找折半位置处的元素是否大于新添加的元素,比如一个size=32的数组,折半查找过程是 32 / 2 = 16、16 / 2 = 8 、8 / 2 = 4、4 / 2 = 2 、 2 / 2 = 1,从前往后依次查找位置 16、8、4、2、1处的元素是否大于新添加的元素(Object[size]),如果不大于,则停止后续的查找,这就解释了上面说的局部有序的问题,这个局部不确定,根据添加的元素有关系,但是基本保证了小的值在前,大的在后。
POP:
pop操作就是把队列头的数据取出,取出后会将最后一个元素放到第一位,然后再执行downHeap的操作,这个操作和upHeap差不多,只是方向是从前往后,不断折半找到一个第一个位数大的元素,找到就调换位置,没有找到就结束
Lucene PriorityQueue & JDK PriorityQueue的更多相关文章
- JDK源码分析实战系列-PriorityQueue
完全二叉树 一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下.从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树 ...
- Java中的集合(四)PriorityQueue常用方法
Java中的集合(四)PriorityQueue常用方法 PriorityQueue的基本概念等都在上一篇已说明,感兴趣的可以点击 Java中的集合(三)继承Collection的Queue接口 查看 ...
- 计算机程序的思维逻辑 (46) - 剖析PriorityQueue
上节介绍了堆的基本概念和算法,本节我们来探讨堆在Java中的具体实现类 - PriorityQueue. 我们先从基本概念谈起,然后介绍其用法,接着分析实现代码,最后总结分析其特点. 基本概念 顾名思 ...
- 计算机程序的思维逻辑 (47) - 堆和PriorityQueue的应用
45节介绍了堆的概念和算法,上节介绍了Java中堆的实现类PriorityQueue,PriorityQueue除了用作优先级队列,还可以用来解决一些别的问题,45节提到了如下两个应用: 求前K个最大 ...
- Java中的队列Queue,优先级队列PriorityQueue
队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...
- PriorityQueue
基本概念 顾名思义,PriorityQueue是优先级队列,它首先实现了队列接口(Queue),与LinkedList类似,它的队列长度也没有限制,与一般队列的区别是,它有优先级的概念,每个元素都有优 ...
- java中PriorityQueue优先级队列使用方法
优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...
- 数据结构【三】:简单优先队列PriorityQueue
在数据结构[二]:简单阻塞队列BlockingQueue的基础上添加权限属性:priority,并控制enqueue时根据priority排序插入. 1.定义priority取值范围0~9 2.deq ...
- 优先队列(priorityqueue)
队列是先进先出的线性表,顾名思义,优先队列则是元素有优先级的队列,出列的顺序由元素的优先级决定.从优先队列中删除元素是根据优先权的高低次序,而不是元素进入队列的次序.优先队列的典型应用是机器调度等. ...
随机推荐
- 笔记8:Linux知识
linux学习笔记 1 Linux介绍 1.1 基本知识 应用领域:服务器使用 LAMP(Linux + Apache + MySQL + PHP)或 LNMP(Linux + Nginx+ MySQ ...
- idea快捷键的使用
IntelliJ IDEA 问题解决:1.乱码,主要是快捷键的字样显示乱码 中文字体显示乱码? 2.菜单项等的字体太小,怎么能设置下? -------------------------------- ...
- c# 第14节 字符方法、转义字符、字符串的方法
本节内容: 1:字符的定义 2:字符的方法 3: 转义字符 4:字符串简介 5:字符串方法 1:字符的定义 char与Unicode一一对应,一个char 2个字节. 2:字符的使用方法: 实例: s ...
- logrotate日志管理工具与split文件切割命令
概述 logrotate是一个Linux系统默认安装了的日志文件管理工具,用来把旧文件轮转.压缩.删除,并且创建新的日志文件.我们可以根据日志文件的大小.天数等来转储,便于对日志文件管理. logro ...
- centos 7 服务初始化
更新yum源及必要软件安装 yum groupinstall "Development tools" "Compatibility libraries" yum ...
- MySQL 5.5/5.6/5.7及以上版本安装包安装时如何选择安装路径
安装环境需求: 自从昨天安装了mysql 5.7,发现了一个问题,mysql5.6起,已经不支持2003系统了,如果安装了无法开启服务而且会出现在 本地计算机 无法启动 MySQL57 服务.错误 1 ...
- JVM-卡表(Card Table)
简介 现代JVM,堆空间通常被划分为新生代和老年代.由于新生代的垃圾收集通常很频繁,如果老年代对象引用了新生代的对象,那么,需要跟踪从老年代到新生代的所有引用,从而避免每次YGC时扫描整个老年代,减少 ...
- Python DataFrame 按条件筛选数据
原始数据如下. 比如我想查看id等于11396的数据. pdata1[pdata1['id']==11396] 查看时间time小于25320的数据. pdata1[pdata1['time']< ...
- Java的十三个设计模式
OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使用现有的类的所有功能,并在无 ...
- 洛谷 P1156 垃圾陷阱 题解
题目传送门 dp+排序+01背包 就完事了??? 貌似就是这样的 代码: //dp 排序 01背包 #include<iostream> #include<cstdio> #i ...