0

0

如何在Java中使用PriorityQueue Java优先队列用法详解

雪夜

雪夜

发布时间:2025-07-16 16:29:02

|

390人浏览过

|

来源于php中文网

原创

java中的priorityqueue是一种基于堆实现的优先队列,其核心特性是每次取出优先级最高的元素。1. 它提供了多种构造函数,包括默认容量和排序方式、指定容量、自定义比较器以及从集合初始化;2. 常用方法如offer/add插入元素、poll/remove移除元素、peek查看队首、size获取大小、contains检查是否存在,其中offer更安全,poll和remove时间复杂度为o(log n),peek和size为o(1),contains为o(n);3. 可通过实现comparator接口自定义排序规则,并在构造时传入比较器;4. 与treeset不同,priorityqueue底层是堆,只保证队首有序,而treeset基于红黑树,所有元素有序且支持索引,但两者均不允许null元素,适用场景各有侧重。

如何在Java中使用PriorityQueue Java优先队列用法详解

Java中的PriorityQueue是一种特殊的队列,它允许我们按照元素的优先级来处理它们。简单来说,你可以把它想象成一个自动排序的队列,每次取出的是优先级最高的元素。

如何在Java中使用PriorityQueue Java优先队列用法详解

PriorityQueue的本质是一个堆(通常是小根堆),这意味着队列中的元素总是按照某种顺序排列,保证队首元素是最小(或最大,取决于你的比较器)。

解决方案

使用PriorityQueue的关键在于理解它的构造函数和常用方法。

立即学习Java免费学习笔记(深入)”;

如何在Java中使用PriorityQueue Java优先队列用法详解
  1. 构造函数:

    Android 开发者指南 第一部分:入门
    Android 开发者指南 第一部分:入门

    Android文档-开发者指南-第一部分:入门-中英文对照版 Android提供了丰富的应用程序框架,它允许您在Java语言环境中构建移动设备的创新应用程序和游戏。在左侧导航中列出的文档提供了有关如何使用Android的各种API来构建应用程序的详细信息。第一部分:Introduction(入门) 0、Introduction to Android(引进到Android) 1、Application Fundamentals(应用程序基础) 2、Device Compatibility(设备兼容性) 3、

    下载
    • PriorityQueue():创建一个具有默认初始容量(11)的 PriorityQueue,并根据其元素的自然顺序对其进行排序。
    • PriorityQueue(int initialCapacity):创建一个具有指定初始容量的 PriorityQueue,并根据其元素的自然顺序对其进行排序。
    • PriorityQueue(Comparator super E> comparator):创建一个具有默认初始容量的 PriorityQueue,并根据指定的比较器对其元素进行排序。
    • PriorityQueue(int initialCapacity, Comparator super E> comparator):创建一个具有指定初始容量的 PriorityQueue,并根据指定的比较器对其元素进行排序。
    • PriorityQueue(Collection extends E> c):创建一个包含指定集合中的元素的 PriorityQueue。
    • PriorityQueue(PriorityQueue extends E> c):创建一个包含指定优先级队列中的元素的 PriorityQueue。
    • PriorityQueue(SortedSet extends E> c):创建一个包含指定排序集合中的元素的 PriorityQueue。
  2. 常用方法:

    如何在Java中使用PriorityQueue Java优先队列用法详解
    • add(E e) / offer(E e):将指定的元素插入此优先级队列。offer 通常更安全,因为它在队列满时返回 false 而不是抛出异常。
    • peek():检索但不移除此队列的头,如果此队列为空,则返回 null
    • poll():检索并移除此队列的头,如果此队列为空,则返回 null
    • remove(Object o):从此队列中移除指定元素的单个实例(如果存在)。
    • contains(Object o):如果此队列包含指定元素,则返回 true
    • size():返回此队列中的元素数量。
    • clear():从此队列中移除所有元素。
    • iterator(): 返回在此队列中的元素上进行迭代的迭代器。

示例代码:

import java.util.PriorityQueue;
import java.util.Comparator;

public class PriorityQueueExample {

    public static void main(String[] args) {
        // 使用默认自然顺序的 PriorityQueue (小根堆)
        PriorityQueue pq1 = new PriorityQueue<>();
        pq1.add(5);
        pq1.add(1);
        pq1.add(10);
        pq1.add(3);

        System.out.println("Default PriorityQueue:");
        while (!pq1.isEmpty()) {
            System.out.print(pq1.poll() + " "); // 输出: 1 3 5 10
        }
        System.out.println();

        // 使用自定义 Comparator 的 PriorityQueue (大根堆)
        PriorityQueue pq2 = new PriorityQueue<>(Comparator.reverseOrder());
        pq2.add(5);
        pq2.add(1);
        pq2.add(10);
        pq2.add(3);

        System.out.println("Custom Comparator PriorityQueue:");
        while (!pq2.isEmpty()) {
            System.out.print(pq2.poll() + " "); // 输出: 10 5 3 1
        }
        System.out.println();

        // 使用自定义对象的 PriorityQueue
        PriorityQueue taskQueue = new PriorityQueue<>(Comparator.comparingInt(Task::getPriority));
        taskQueue.add(new Task("Task A", 3));
        taskQueue.add(new Task("Task B", 1));
        taskQueue.add(new Task("Task C", 2));

        System.out.println("Task PriorityQueue:");
        while (!taskQueue.isEmpty()) {
            System.out.println(taskQueue.poll());
        }
    }

    static class Task {
        private String name;
        private int priority;

        public Task(String name, int priority) {
            this.name = name;
            this.priority = priority;
        }

        public String getName() {
            return name;
        }

        public int getPriority() {
            return priority;
        }

        @Override
        public String toString() {
            return "Task{" +
                    "name='" + name + '\'' +
                    ", priority=" + priority +
                    '}';
        }
    }
}

PriorityQueue 的时间复杂度是多少?

  • offer(E e)add(E e): O(log n),其中 n 是队列中的元素数量。这是因为插入元素后需要调整堆结构。
  • poll()remove(Object o): O(log n),其中 n 是队列中的元素数量。移除元素后也需要调整堆结构。
  • peek(): O(1),因为只是查看堆顶元素,不需要调整堆。
  • size(): O(1),直接返回队列的大小。
  • contains(Object o): O(n),在最坏情况下需要遍历整个队列来查找元素。

如何自定义 PriorityQueue 的排序规则?

可以通过实现 Comparator 接口来定义自定义的排序规则。Comparator 接口允许你指定两个对象之间的比较方式。 在创建 PriorityQueue 实例时,将自定义的 Comparator 传递给构造函数。

import java.util.PriorityQueue;
import java.util.Comparator;

public class CustomPriorityQueue {

    public static void main(String[] args) {
        // 自定义 Comparator,按照字符串长度降序排列
        Comparator stringLengthComparator = (s1, s2) -> s2.length() - s1.length();

        PriorityQueue stringQueue = new PriorityQueue<>(stringLengthComparator);
        stringQueue.add("apple");
        stringQueue.add("banana");
        stringQueue.add("kiwi");
        stringQueue.add("orange");

        System.out.println("Custom String PriorityQueue:");
        while (!stringQueue.isEmpty()) {
            System.out.println(stringQueue.poll()); // 输出: banana, orange, apple, kiwi
        }
    }
}

PriorityQueue 和 TreeSet 的区别是什么?

PriorityQueueTreeSet 都是用于存储有序元素的集合,但它们在实现和使用上有一些关键区别:

  • 底层数据结构: PriorityQueue 基于堆(通常是小根堆)实现,而 TreeSet 基于红黑树实现。
  • 排序方式: PriorityQueue 只保证队首元素是最小(或最大)的,其他元素的顺序不确定。 TreeSet 则保证所有元素都是有序的。
  • 是否允许 null 元素: PriorityQueue 不允许存储 null 元素,会抛出 NullPointerExceptionTreeSet 也不允许存储 null 元素(在大多数实现中)。
  • 时间复杂度: PriorityQueueofferpoll 操作的时间复杂度为 O(log n),peek 操作为 O(1)。 TreeSetaddremovecontains 操作的时间复杂度都为 O(log n)。
  • 应用场景: PriorityQueue 适用于需要频繁获取最小(或最大)元素的场景,例如任务调度、堆排序等。 TreeSet 适用于需要维护有序集合的场景,例如字典、索引等。

简单来说,如果只需要获取优先级最高的元素,使用 PriorityQueue 效率更高。如果需要维护一个完全有序的集合,使用 TreeSet 更合适。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

236

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

458

2024.03.01

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

544

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

93

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

200

2025.08.29

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

538

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 7.9万人学习

Java 教程
Java 教程

共578课时 | 52.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号