PriorityQueue是Java中基于优先级出队的队列,默认为小顶堆,每次取出最小元素;其核心方法包括add/offer入队、poll出队、peek查看队首;与普通FIFO队列不同,它按元素优先级排序而非入队顺序;可通过实现Comparable接口或传入Comparator自定义排序规则;常用于Dijkstra算法、任务调度、Top K问题等需动态处理最高优先级元素的场景。

Java里的
PriorityQueue
我个人觉得,理解
PriorityQueue
首先,创建它。如果你想用默认的自然排序(比如数字从小到大),直接
new PriorityQueue<Integer>()
Comparator
// 默认小顶堆,存储整数
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// 大顶堆,存储整数
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a); // 或者 Comparator.reverseOrder()
// 存储自定义对象,假设有一个Task类,根据priority字段排序
class Task {
String name;
int priority; // 优先级,数字越小优先级越高
public Task(String name, int priority) {
this.name = name;
this.priority = priority;
}
@Override
public String toString() {
return "Task{" + "name='" + name + '\'' + ", priority=" + priority + '}';
}
}
PriorityQueue<Task> taskQueue = new PriorityQueue<>(Comparator.comparingInt(t -> t.priority));接着是往里面加元素,用
add()
offer()
offer()
false
PriorityQueue
立即学习“Java免费学习笔记(深入)”;
minHeap.add(3);
minHeap.offer(1);
minHeap.add(2);
System.out.println("当前队列 (内部表示,不保证顺序): " + minHeap); // 内部顺序不保证,但poll()会取1然后就是取元素。
peek()
poll()
System.out.println("队首元素 (不移除): " + minHeap.peek()); // 输出 1
System.out.println("移除队首元素: " + minHeap.poll()); // 输出 1
System.out.println("移除后的队首元素: " + minHeap.peek()); // 输出 2
System.out.println("队列大小: " + minHeap.size()); // 输出 2
System.out.println("队列是否为空: " + minHeap.isEmpty()); // 输出 false有时候,我发现新手会忘记
poll()
说实话,这个问题我被问过好多次,也自己琢磨过。最核心的区别,我觉得,就在于“出队顺序”的决定机制。普通队列,比如
LinkedList
Queue
但
PriorityQueue
PriorityQueue
poll()
add()
PriorityQueue
自定义排序规则是
PriorityQueue
第一种是让你的元素类实现
Comparable
Comparable
compareTo
PriorityQueue
class Student implements Comparable<Student> {
String name;
int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
// 假设分数越高优先级越高,所以是降序
@Override
public int compareTo(Student other) {
return other.score - this.score; // 大顶堆,分数高的先出
}
@Override
public String toString() {
return "Student{" + "name='" + name + '\'' + ", score=" + score + '}';
}
}
// 使用自然排序(即Student类中定义的compareTo)
PriorityQueue<Student> highScorers = new PriorityQueue<>();
highScorers.add(new Student("Alice", 90));
highScorers.add(new Student("Bob", 95));
highScorers.add(new Student("Charlie", 88));
System.out.println("最高分学生: " + highScorers.poll()); // Bob第二种,也是更灵活的方式,是给
PriorityQueue
Comparator
// 使用Lambda表达式定义Comparator,实现按名字长度排序(短的优先)
PriorityQueue<String> byLength = new PriorityQueue<>(Comparator.comparingInt(String::length));
byLength.add("apple");
byLength.add("banana");
byLength.add("cat");
System.out.println("按长度排序: " + byLength.poll()); // cat
// 或者,如果想实现大顶堆(最大值优先),可以这样
PriorityQueue<Integer> customMaxHeap = new PriorityQueue<>((a, b) -> b - a);
customMaxHeap.add(10);
customMaxHeap.add(20);
customMaxHeap.add(5);
System.out.println("自定义大顶堆: " + customMaxHeap.poll()); // 20我个人偏爱使用
Comparator
说起
PriorityQueue
一个经典的例子是Dijkstra最短路径算法。在寻找图中两点间最短路径时,我们总是需要优先处理那些当前已知路径最短的节点。
PriorityQueue
再比如,任务调度系统。想象一下,你有一堆任务,每个任务都有一个优先级或者一个计划执行时间。你需要一个调度器,总是能把当前最紧急或者最先到期的任务拿出来执行。
PriorityQueue
还有,“Top K”问题。比如从海量数据中找出最大的K个元素,或者最小的K个元素。这时,我们可以维护一个大小为K的
PriorityQueue
// 找出数组中最大的K个元素 (使用小顶堆)
int[] nums = {3, 2, 1, 5, 6, 4};
int k = 3;
PriorityQueue<Integer> topKHeap = new PriorityQueue<>(); // 默认小顶堆
for (int num : nums) {
topKHeap.offer(num);
if (topKHeap.size() > k) {
topKHeap.poll(); // 移除最小的,保持堆中是当前遇到的K个最大元素
}
}
System.out.println("最大的K个元素: " + topKHeap); // [4, 5, 6] (内部顺序不保证,但poll会按从小到大)这个例子就很好的说明了,利用
PriorityQueue
此外,事件模拟系统、霍夫曼编码(Huffman Coding)构建最小生成树等算法中,
PriorityQueue
PriorityQueue
以上就是Java中PriorityQueue的基础使用方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号