Java中PriorityQueue默认为最小堆,按自然顺序升序排列;可通过Comparator(如Collections.reverseOrder()、Lambda表达式)或实现Comparable接口来自定义排序规则,如最大堆或按对象字段排序。

Java 中 PriorityQueue 默认按自然顺序(升序)排序,即队首是最小元素;要实现自定义优先级(比如最大堆、按字段排序等),关键在于传入合适的 Comparator 或让元素实现 Comparable 接口。
默认行为:最小堆(自然顺序)
如果元素是 Integer、String 等已实现 Comparable 的类型,PriorityQueue 会自动按其 compareTo() 方法排序:
-
new PriorityQueue<Integer>()→ 小的数字先出(如 1, 3, 5) -
new PriorityQueue<String>()→ 字典序升序("apple" 在 "banana" 前)
实现最大堆:用 Collections.reverseOrder()
最简单的方式是使用内置比较器反转顺序:
-
new PriorityQueue<Integer>(Collections.reverseOrder())→ 大的数字先出 -
new PriorityQueue<String>(Collections.reverseOrder())→ 字典序降序
按对象字段自定义排序:传入 Lambda 或匿名 Comparator
比如有一个 Task 类,想按优先级数字从高到低(即最大优先级先处理):
立即学习“Java免费学习笔记(深入)”;
class Task {
String name;
int priority; // 数值越大,优先级越高
Task(String name, int priority) {
this.name = name;
this.priority = priority;
}
}构造优先队列时传入比较逻辑:
- Lambda 写法:
new PriorityQueue<Task>((a, b) -> b.priority - a.priority) - 或更安全的写法(避免整数溢出):
(a, b) -> Integer.compare(b.priority, a.priority) - 也可用方法引用:
Comparator.comparingInt((Task t) -> t.priority).reversed()
让类自己支持排序:实现 Comparable
如果 Task 总是按同一规则排序,可直接实现接口:
class Task implements Comparable<Task> {
int priority;
public Task(int priority) { this.priority = priority; }
@Override
public int compareTo(Task other) {
return Integer.compare(other.priority, this.priority); // 降序
}
}这样 new PriorityQueue<Task>() 就自动按优先级从高到低排序,无需额外传 Comparator。
PriorityQueue 的排序逻辑只在入队(offer)、出队(poll)和查看队首(peek)时起作用,内部用堆结构维护,不是每次操作都全量排序。只要比较器逻辑一致、不违反传递性,就能稳定按优先级工作。


















