PriorityQueue是基于无界优先级队列和优先级堆构建的重要Java API之一。本文通过适当的代码示例深入了解了有关此API及其用法的一些复杂信息。另在上篇文章中我们简单地谈了下Java编译器API简介,你可以先阅读以方便更好地阅读这篇文章。感谢优锐课老师对我写下这两篇文章时给予的帮助。

总览

PriorityQueue类是java.util包的一部分,是Java中基于优先级的队列的通用实现。队列基本上是一种数据结构,它定义了针对商店中商品的插入和检索过程的特定规范。这个想法与排队等候说票的许多人非常相似。排队的第一个人有第一个获得彩票的机会,最后一个人有一个结局的机会。人们被添加到队列的末尾或末尾。在队列中添加项目在技术上称为入队过程,从队列中删除的项目是从该行的第一行开始。这称为出队。想法是以先进先出的方式对元素进行排序。

现在,这是最简单的体系结构,并且紧密定义了队列的实际含义以及如何在计算机中模拟队列。存储通常由一个简单的数组表示,其中存储和检索过程具有此定义的规范。优先级队列在此之上强加一些特殊规范。我们将在后面看到更多内容。

队列的Java实现

Java API在java.util包中具有通用接口名称Queue <E>。这是Java Collection Framework API的一部分,旨在在处理之前保存元素。作为集合的一部分,它具有所有基本的集合操作。特定于其标识的操作涉及存储在其中的元素的插入,提取和检查。这些操作中的每一个都有两种不同的形式,例如一种在操作失败时引发异常,而另一种则根据操作返回一个特殊值,例如null或false。请注意,与典型队列不同,Java Queue的具体实现不必一定以FIFO方式对元素进行排序。对于基于优先级的队列尤其如此,其中元素的排序是根据提供的比较器或自然排序完成的。但是无论顺序如何,remove()或poll()方法将始终检索队列开头的元素。这两种不太可能的方法之间的特定区别似乎是一种相似的方法,即在失败时引发异常(NoSuchElementException),而后者则返回特殊值(null)。

方法

引发异常

描述

E remove()

NoSuchElementException

从队列的开头检索一个元素。

void add(E)

IllegalStateException

在队列末尾插入一个元素。成功返回true,如果空间不可用则抛出异常。

E element()

NoSuchElementException

检索元素而不将其从队列的开头移除。

 

方法

返回特殊值

说明

boolean offer(E)

true or false

将元素插入队列。成功返回true,如果由于空间不足而无法插入,则返回false。

E poll()

null

从队列的开头移除元素;如果队列为空,则返回null。

E peek()

null

检索但不从队列的开头删除元素。如果队列为空,则返回null。

           

请注意,Queue <E>接口不适用于并发编程,因为它没有定义阻塞队列方法,在这种方法中,入队和出队过程等待元素出现在队列中或大小可用。有一个名为BlockingQueue <E>的特定接口,该接口扩展了Queue <E>接口并解决了这些问题。

有一个称为AbstractQueue <E>的抽象类,该类提供某些队列操作的部分实现。 PriorityQueue <E>类是此抽象类的直接扩展。

优先队列

优先级队列的Java实现是一种特殊的队列,其中元素的排序由其自然排序原则确定,也可以根据创建期间提供的Comparator进行定制。我们在构造过程中调用的构造函数决定要与优先级队列一起使用的排序原则。与不允许使用null元素的Queue <E>不同,但是某些实现(例如LinkedList)也不禁止插入null元素。但是,PriorityQueue <E>根本不允许空元素。如果优先级队列是根据自然顺序构造的,则任何不可比较的元素插入都将引发ClassCastException。

它被声明为无限制的并且基于优先级堆。尽管队列的大小被称为无限制,但内部具有确定阵列大小的能力。插入元素时,此大小会自动增长。但是,没有详细说明增大尺寸的原理。

有七种类型的重载构造函数,通过它们我们可以设置参数来指定队列的初始容量,提供Comparator来指定元素的自定义顺序,或者使用无参数构造函数将所有内容接受为默认值。

  • PriorityQueue()
  • PriorityQueue(int initialCapacity)
  • PriorityQueue(int initialCapacity, Comparator<? Super E> comparator)
  • PriorityQueue(Commection<? extends E> c)
  • PriorityQueue(Comparator<? Super E> comparator)
  • PriorityQueue(PriorityQueue<? extends E> c)
  • PriorityQueue(SortedSet<? extends E> c)

与Queue <E>相似,PriorityQueue <E>也不同步,因此在并发编程中应谨慎使用。但是,有一个同步的替代方法,称为PriorityBlockingQueue <E>。这与PriorityQueue <E>的工作方式相同,只是具有线程安全的其他限定条件。

PriorityQueue <E>中定义的操作与Queue <E>相同,但有一些附加功能。

方法

描述

void clear()

从优先级队列中删除所有元素。

Comparator<? Super E> comparator()

返回与队列关联的比较器。如果根据自然顺序对队列进行排序,则返回null。

boolean contains(Object o)

如果队列包含指定的对象,则返回true。

Iterator<E> iterator()

返回与Collection类关联的旧式迭代器。但是,它不能保证以任何特定顺序遍历元素。

Spliterator<E> spliterator()

创建后期绑定,故障快速拆分器,但具有与迭代器相同的条件。

Object[] toArray()

这是一种便捷方法,可用于设置遍历顺序权限,例如Arrays.sort(priorityQueue.toArray()).

<T>T[] toArray(T[] a)

返回数组元素,但是返回类型由指定的数组确定。

快速示例1

让我们用一个简单的程序实现PriorityQueue <E>的一些操作。

 package org.mano.examples;
import java.util.Arrays;
import java.util.Iterator;
import java.util.PriorityQueue;
public class Example1 {
public static void main(String[] args){
PriorityQueue<String> pq = new PriorityQueue<>();
pq.add("Mercury");
pq.add("Venus");
pq.add("Earth");
pq.add("Mars");
pq.add("Jupiter");
pq.add("Saturn");
// Get the most priority element based upon
// natural alphabetic ordering in string
System.out.println("Priority element "+pq.peek());
// Queue elements
show(pq);
// Remove top of the queue element
pq.poll();
show(pq);
// Retrieves element from the head of the queue
pq.remove("Earth");
show(pq);
String result = pq.contains("Earth")?
"Found Earth":"Earth Missing!";
System.out.println(result);
Object[] arr = pq.toArray();
Arrays.sort(arr);
System.out.println("");
for (int i = 0; i<arr.length; i++)
System.out.print(arr[i].toString()+"::");
}
public static void show(PriorityQueue<String> pq){
Iterator<String> itr = pq.iterator();
while (itr.hasNext())
System.out.print(itr.next()+"::");
System.out.println("");
}
}

Output

 Priority element Earth
Earth::Jupiter::Mercury::Venus::Mars::Saturn::
Jupiter::Mars::Mercury::Venus::Saturn::
Jupiter::Mars::Mercury::Venus::Saturn::
Earth Missing! Jupiter::Mars::Mercury::Saturn::Venus::

快速示例2

这是另一个带有自定义比较器的快速示例。

 package org.mano.examples;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Planet implements Comparable<Planet>{
private String name;
private double orbitPeriodInDays;
public Planet(String name, double orbitPeriodInDays) {
this.name = name;
this.orbitPeriodInDays = orbitPeriodInDays;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getOrbitPeriodInDays() {
return orbitPeriodInDays;
}
public void setOrbitPeriodInDays(double orbitPeriodInDays) {
this.orbitPeriodInDays = orbitPeriodInDays;
}
@Override
public int compareTo(Planet o) {
return 0;
}
@Override
public String toString() {
return "Planet{" +
"name='" + name + '\'' +
", orbitPeriodInDays=" + orbitPeriodInDays +
'}';
}
public static void main(String[] args){
Comparator<Planet> nameSorter =
Comparator.comparing(Planet::getName);
PriorityQueue<Planet> priorityQueue = new
PriorityQueue<>(nameSorter);
priorityQueue.add(new Planet("Mercury",88));
priorityQueue.add(new Planet("Venus",225));
priorityQueue.add(new Planet("Earth",365.24));
priorityQueue.add(new Planet("Mars",693.5));
priorityQueue.add(new Planet("Jupiter",4343.5));
priorityQueue.add(new Planet("Saturn",10767.5));
priorityQueue.add(new Planet("Uranus",30660));
priorityQueue.add(new Planet("Neptune",60152));
Object[] list = priorityQueue.toArray();
for (Object o: list)
System.out.println(o);
}
}

Output

 Planet{name='Earth', orbitPeriodInDays=365.24}
Planet{name='Jupiter', orbitPeriodInDays=4343.5}
Planet{name='Mercury', orbitPeriodInDays=88.0}
Planet{name='Neptune', orbitPeriodInDays=60152.0}
Planet{name='Mars', orbitPeriodInDays=693.5}
Planet{name='Saturn', orbitPeriodInDays=10767.5}
Planet{name='Uranus', orbitPeriodInDays=30660.0}
Planet{name='Venus', orbitPeriodInDays=225.0}

总结

优先级队列的其他规范是,从列表中删除的项目具有最高优先级。Java将优先级规则强加给其他常规队列的方式是通过附加元素的排序原则。该顺序可以根据程序员的要求进行自定义,也可以设置为默认。这就是Java中优先级队列实现的本质。

感谢阅读!

什么是Java优先级队列?的更多相关文章

  1. Java优先级队列

    package com.lk.A; import java.util.PriorityQueue; public class Test5 { public static void main(Strin ...

  2. JAVA优先级队列元素输出顺序测试

    package code.test; import java.util.Comparator; import java.util.Iterator; import java.util.Priority ...

  3. Java优先级队列实现

    优先级队列数组实现: public class PriorityQueue { private int[] data; private int size; public PriorityQueue(i ...

  4. 什么是Java优先级队列(Priority Queue)?

    PriorityQueue是一个基于优先级堆的无界队列.它的元素是按照自然顺序排序的.在创建元素的时候,我们给它一个一个负责排序的比较器.PriorityQueue不允许null值,因为 它们没有自然 ...

  5. java优先级队列的使用 leecode.703.数据流中的第K大元素

    //设计一个找到数据流中第K大元素的类(class). //注意是排序后的第K大元素,不是第K个不同的元素. class KthLargest { private PriorityQueue<I ...

  6. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

  7. java中PriorityQueue优先级队列使用方法

    优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最高优先权的元素. PriorityQueue是从JDK1.5开始提供的新的数据结构接口. 如果不提供Comparator的话,优先 ...

  8. java PriorityBlockingQueue 基于优先级队列,的读出操作可以阻止.

    java PriorityBlockingQueue 基于优先级队列.的读出操作可以阻止. package org.rui.thread.newc; import java.util.ArrayLis ...

  9. 《转》JAVA中PriorityQueue优先级队列使用方法

    该文章转自:http://blog.csdn.net/hiphopmattshi/article/details/7334487 优先级队列是不同于先进先出队列的另一种队列.每次从队列中取出的是具有最 ...

随机推荐

  1. vue 解决跨域

    先上报错 以表尊重 在vue中 找到 config文件夹中的 index.js文件  配置更改如下 proxyTable: { '/api': { target: 'http://47.240.11. ...

  2. Redis系列(二):Redis高可用集群

    一.集群模式 Redis集群是一个由多个主从节点组成的高可用集群,它具有复制.高可用和分片等特性 二.集群部署 1.环境 3台主机分别是: 192.168.160.146 192.168.160.15 ...

  3. 英语口语考试资料College life

    College life Early in senior high school, we longed to be enrolled in a university. Now the dream ha ...

  4. Java学习笔记1(基础)

    计算机语言和Java 计算机语言主要由一些指令(包括数字.符号和语法等)组成,可以分为机器语言.汇编语言.高级语言三大类.Java是一种高级计算机语言,是一种可以编写跨平台应用软件.完全面向对象的程序 ...

  5. 硬核评测:企业上云的极速存储挑战,华为云全新极速IO云硬盘性能评测

    来源:至顶网 作者:董培欣 借助华为云全新一代极速IO云硬盘开启邀测的时机,至顶网评测实验室展开了一次华为云极速IO云硬盘与超高IO云硬盘的性能对比测试活动,并且尝试通过相关测试成绩,对云硬盘的应用能 ...

  6. 鲲鹏性能优化十板斧之前言 | 鲲鹏处理器NUMA简介与性能调优五步法

    鲲鹏处理器NUMA简介 随着现代社会信息化.智能化的飞速发展,越来越多的设备接入互联网.物联网.车联网,从而催生了庞大的计算需求.但是功耗墙问题以功耗和冷却两大限制极大的影响了单核算力的发展.为了满足 ...

  7. Spring Quartz定时任务设置

    这里主要记录一下定时任务的配置,偏向于记录型的一个教程,这里不阐述Quartz的原理. 首先,在Spring配置文件里配置一个自己写好的一个包含执行任务方法的一个类. <bean id=&quo ...

  8. 浅议Grpc传输机制和WCF中的回调机制的代码迁移

    浅议Grpc传输机制和WCF中的回调机制的代码迁移 一.引子 如您所知,gRPC是目前比较常见的rpc框架,可以方便的作为服务与服务之间的通信基础设施,为构建微服务体系提供非常强有力的支持. 而基于. ...

  9. oracle逻辑存储结构

    oracle数据库管理系统有三个重要的概念:实例.数据库.数据库服务器.oracle数据库的存储结构可以分为逻辑存储结构和物理存储结构.逻辑存储结构用于描绘Oracle内部组织和管理数据的方式,而物理 ...

  10. kafka - java.nio.file.FileSystemException

    在启动Kafka时报错无法启动 E:\kafka_2.12-2.3.1\kafka-logs\__consumer_offsets-48\00000000000000000000.timeindex. ...