PriorityQueue和PriorityBlockingQueue

2024-02-24 16:48

本文主要是介绍PriorityQueue和PriorityBlockingQueue,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 简介
  • PriorityQueue
  • PriorityBlockingQueue

PriorityQueue和PriorityBlockingQueue

简介

Queue一般来说都是FIFO的,当然之前我们也介绍过Deque可以做为栈来使用。今天我们介绍一种PriorityQueue,可以安装对象的自然顺序或者自定义顺序在Queue中进行排序。

PriorityQueue

先看PriorityQueue,这个Queue继承自AbstractQueue,是非线程安全的。

PriorityQueue的容量是unbounded的,也就是说它没有容量大小的限制,所以你可以无限添加元素,如果添加的太多,最后会报OutOfMemoryError异常。

这里教大家一个识别的技能,只要集合类中带有CAPACITY的,其底层实现大部分都是数组,因为只有数组才有capacity,当然也有例外,比如LinkedBlockingDeque。

只要集合类中带有comparator的,那么这个集合一定是个有序集合。

我们看下PriorityQueue:

private static final int DEFAULT_INITIAL_CAPACITY = 11;private final Comparator<? super E> comparator;

定义了初始Capacity和comparator,那么PriorityQueue的底层实现就是Array,并且它是一个有序集合。

有序集合默认情况下是按照natural ordering来排序的,如果你传入了 Comparator,则会按照你指定的方式进行排序,我们看两个排序的例子:

@Slf4j
public class PriorityQueueUsage {@Testpublic void usePriorityQueue(){PriorityQueue<Integer> integerQueue = new PriorityQueue<>();integerQueue.add(1);integerQueue.add(3);integerQueue.add(2);int first = integerQueue.poll();int second = integerQueue.poll();int third = integerQueue.poll();log.info("{},{},{}",first,second,third);}@Testpublic void usePriorityQueueWithComparator(){PriorityQueue<Integer> integerQueue = new PriorityQueue<>((a,b)-> b-a);integerQueue.add(1);integerQueue.add(3);integerQueue.add(2);int first = integerQueue.poll();int second = integerQueue.poll();int third = integerQueue.poll();log.info("{},{},{}",first,second,third);}
}

默认情况下会按照升序排列,第二个例子中我们传入了一个逆序的Comparator,则会按照逆序排列。

PriorityBlockingQueue

PriorityBlockingQueue是一个BlockingQueue,所以它是线程安全的。

我们考虑这样一个问题,如果两个对象的natural ordering或者Comparator的顺序是一样的话,两个对象的顺序还是固定的吗?

出现这种情况,默认顺序是不能确定的,但是我们可以这样封装对象,让对象可以在排序顺序一致的情况下,再按照创建顺序先进先出FIFO的二次排序:

public class FIFOEntry<E extends Comparable<? super E>>implements Comparable<FIFOEntry<E>> {static final AtomicLong seq = new AtomicLong(0);final long seqNum;final E entry;public FIFOEntry(E entry) {seqNum = seq.getAndIncrement();this.entry = entry;}public E getEntry() { return entry; }public int compareTo(FIFOEntry<E> other) {int res = entry.compareTo(other.entry);if (res == 0 && other.entry != this.entry)res = (seqNum < other.seqNum ? -1 : 1);return res;}
}

上面的例子中,先比较两个Entry的natural ordering,如果一致的话,再按照seqNum进行排序。

本文的例子https://github.com/ddean2009/learn-java-collections

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

欢迎关注我的公众号:程序那些事,更多精彩等着您!
更多内容请访问 www.flydean.com

这篇关于PriorityQueue和PriorityBlockingQueue的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/742735

相关文章

JDK8中关于最小堆的实现(PriorityBlockingQueue)

java.util.concurrent.PriorityBlockingQueue#siftUpComparable 代码很简单,记录一下。 /*** Inserts item x at position k, maintaining heap invariant by* promoting x up the tree until it is greater than or eq

堆-数组的堆化+优先队列(PriorityQueue)的使用

一、堆 1、什么是堆? 以完全二叉树的形式将元素存储到对应的数组位置上所形成的新数组 2、为什么要将数组变成堆? 当数组中的元素连续多次进行排序时会消耗大量的时间,将数组变成堆后通过堆排序的方式将会消耗更少的时间 二、接口 给堆定义一个接口,用来规范堆里面的方法 1、在获取堆顶元素和删除堆顶元素的方法中,都必须返回堆顶元素,当堆为空时,返回异常对象要比返回null关键字更加安全 定

【Java编程的逻辑】堆与优先级队列PriorityQueue

完全二叉树 & 满二叉树 & 堆 基本概念 满二叉树是指除了最后一层外,每个节点都有两个孩子,而最后一层都是叶子节点,都没有孩子。 满二叉树一定是完全二叉树,但完全二叉树不要求最后一层是满的,但如果不满,则要求所有节点必须集中在最左边,从左到右是连续的,中间不能有空的。 特点 在完全二叉树中,可以给每个节点一个编号,编号从1开始连续递增,从上到下,从左到右 完全二叉树有一

PriorityQueue 总结

Find Median from Data Stream 用两个堆来维持关系,左边用最大堆,右边用最小堆,如果num[i] 比最大堆的堆顶小,加入最大堆,否则加入最小堆,然后再调整数目,始终保证最大堆比最小堆数目相等,或者只大于1; class MedianFinder {private PriorityQueue<Integer> maxheap;private PriorityQueue<I

吃透Java集合系列七:PriorityQueue

一:PriorityQueue实现方式 Java中PriorityQueue实现了Queue接口,不允许放入null元素;其通过堆实现,具体说是通过完全二叉树(complete binary tree)实现的小顶堆(任意一个非叶子节点的权值,都不大于其左右子节点的权值),也就意味着可以通过数组来作为PriorityQueue的底层实现。 二:源码分析 重要变量以及构造函数 根据堆的特性,

Java数据结构(七)——优先级队列与PriorityQueue

文章目录 优先级队列与PriorityQueue堆基本概念和性质建堆堆的插入堆的删除堆的应用 PriorityQueuePriorityQueue的构造方法PriorityQueue的常用方法PriorityQueue的模拟实现 经典TopK问题 优先级队列与PriorityQueue 优先级队列是一种特殊类型的队列,其中元素按照优先级进行排序,最高优先级的元素最先被取出。其概

API学习PriorityQueue

package com.wonders.week01.collection;import java.util.Iterator;import java.util.PriorityQueue;/*** JDK1.7* PriorityQueue优先级队列* (1)继承自 AbstractQueue* (2)它是一个基于优先级堆的无界优先队列。* (3)优先级队列的元素的顺序是按照自然顺序或者是按照

PriorityQueue详解(含动画演示)

目录 PriorityQueue详解1、PriorityQueue简介2、PriorityQueue继承体系3、PriorityQueue数据结构PriorityQueue类属性注释完全二叉树、大顶堆、小顶堆的概念☆PriorityQueue是如何利用数组存储小顶堆的?☆利用数组存储完全二叉树的好处? 4、PriorityQueue的`offer`方法动画演示offer插入过程: 5、Pri

PriorityQueue优先队列详解

PriorityQueue优先队列详解 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来详细讲解一下Java中非常重要的数据结构之一——PriorityQueue优先队列。PriorityQueue是Java集合框架中的一部分,用于实现基于优先级的元素排序。它在处理调度任务、路径搜索算法等方面有着广泛的应用。 什么是P

并发之PriorityBlockingQueue简单使用

PriorityBlockingQueue是一个支持优先级的无界阻塞队列,直到系统资源耗尽。默认情况下元素采用自然顺序升序排列。也可以自定义类实现compareTo()方法来指定元素排序规则,或者初始化PriorityBlockingQueue时,指定构造参数Comparator来对元素进行排序。但需要注意的是不能保证同优先级元素的顺序。PriorityBlockingQueue也是基于最小二叉