PriorityQueue基于堆实现,用于任务调度,非线程安全,不允许null,插入删除O(log n),需实现Comparable或Comparator定义优先级。

在Java中,PriorityQueue 是一种基于堆结构的队列实现,能够自动根据元素的优先级进行排序,非常适合用于任务调度、事件处理等需要优先执行高优先级任务的场景。它实现了 Queue 接口,不允许 null 值,插入和删除操作的时间复杂度为 O(log n)。
定义任务类并实现比较逻辑
要使用 PriorityQueue 管理任务,首先需要定义一个任务类,并确定优先级规则。通常通过实现 Comparable 接口或提供 Comparator 来定义排序方式。
例如,定义一个任务类,优先级数值越小表示优先级越高:
class Task implements Comparable{ 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 int compareTo(Task other) { return Integer.compare(this.priority, other.priority); // 优先级小的排前面 } @Override public String toString() { return "Task{name='" + name + "', priority=" + priority + '}'; } }
创建并操作 PriorityQueue
创建 PriorityQueue 实例后,可以使用标准的队列方法添加和取出任务。
立即学习“Java免费学习笔记(深入)”;
示例代码:
import java.util.PriorityQueue;
public class TaskManager {
public static void main(String[] args) {
PriorityQueue taskQueue = new PriorityQueue<>();
// 添加任务
taskQueue.offer(new Task("Send Email", 3));
taskQueue.offer(new Task("Fix Bug", 1));
taskQueue.offer(new Task("Write Report", 2));
// 按优先级处理任务
while (!taskQueue.isEmpty()) {
Task task = taskQueue.poll();
System.out.println("Executing: " + task);
}
}
}
输出结果:
Executing: Task{name='Fix Bug', priority=1}
Executing: Task{name='Write Report', priority=2}
Executing: Task{name='Send Email', priority=3}
使用自定义 Comparator 控制优先级顺序
如果不希望修改任务类的源码,或者需要多种排序策略,可以通过传入 Comparator 来定制优先级规则。
例如,按优先级降序排列(高优先级数字先执行):
PriorityQueuehighToLowQueue = new PriorityQueue<>((t1, t2) -> Integer.compare(t2.getPriority(), t1.getPriority()) );
也可以根据多个字段排序,比如优先级相同则按任务名称字母顺序:
PriorityQueuecomplexQueue = new PriorityQueue<>((t1, t2) -> { int cmp = Integer.compare(t1.getPriority(), t2.getPriority()); if (cmp == 0) { return t1.getName().compareTo(t2.getName()); } return cmp; });
注意事项与常见问题
使用 PriorityQueue 时需注意以下几点:
- PriorityQueue 不是线程安全的,多线程环境下应使用
PriorityBlockingQueue - 遍历队列不会按顺序输出,只有通过
poll()取出时才保证顺序 - 不能直接修改队列中已存在元素的优先级,否则会破坏堆结构。如需更新,应先移除再重新插入
- null 元素不被允许,插入 null 会抛出 NullPointerException










