PriorityQueue是Java中基于优先堆的无界队列,1. 默认实现最小堆,队头为最小元素,适用于Integer、String等Comparable类型;2. 自定义对象需实现Comparable接口或传入Comparator定义优先级,如Task按priority字段排序;3. 可通过Lambda表达式定制排序规则,如(a,b)->b-a构建最大堆;4. 常用于任务调度场景,如ScheduledTask按executeTime升序执行;需注意其非线程安全,高并发应选用PriorityBlockingQueue。

在Java中,PriorityQueue 是一种基于优先堆的无界队列,能够自动根据元素的优先级进行排序,常用于实现任务调度、事件处理等需要优先执行特定任务的场景。它不属于阻塞队列,不支持null元素,且不保证相同优先级元素的顺序。
1. PriorityQueue的基本使用
PriorityQueue默认实现最小堆,即队列头部是当前最小的元素。可以直接存储实现了Comparable接口的对象,如Integer、String等。
// 创建一个最小堆优先队列 PriorityQueuequeue = new PriorityQueue<>(); queue.offer(5); queue.offer(2); queue.offer(8); System.out.println(queue.poll()); // 输出 2 System.out.println(queue.poll()); // 输出 5
每次调用 poll() 都会取出优先级最高的元素(默认最小值)。
2. 自定义对象与优先级规则
若要存储自定义对象(如任务),需提供比较逻辑。可通过实现 Comparable 接口或传入 Comparator 来实现。
立即学习“Java免费学习笔记(深入)”;
class Task implements Comparable{ String name; int priority; // 数值越小,优先级越高 public Task(String name, int priority) { this.name = name; this.priority = priority; } @Override public int compareTo(Task other) { return Integer.compare(this.priority, other.priority); }}
// 使用 PriorityQueue
taskQueue = new PriorityQueue(); taskQueue.offer(new Task("清理缓存", 3)); taskQueue.offer(new Task("保存日志", 1)); taskQueue.offer(new Task("发送通知", 2)); while (!taskQueue.isEmpty()) { System.out.println(taskQueue.poll().name); } // 输出顺序:保存日志 → 发送通知 → 清理缓存
3. 使用Comparator定制排序
若不想修改类结构,可使用 Comparator 在构造时指定排序方式。
PriorityQueuequeue = new PriorityQueue<>((a, b) -> Integer.compare(a.priority, b.priority) );
也可反转顺序实现最大堆:
PriorityQueuemaxHeap = new PriorityQueue<>((a, b) -> b - a); maxHeap.offer(3); maxHeap.offer(1); maxHeap.offer(4); System.out.println(maxHeap.poll()); // 输出 4
4. 实际应用场景示例:任务调度器
模拟一个任务调度系统,按紧急程度执行任务。
class ScheduledTask {
String description;
long executeTime; // 执行时间戳(越早越优先)
public ScheduledTask(String desc, long time) {
this.description = desc;
this.executeTime = time;
}}
// 按执行时间升序排列
PriorityQueue scheduler =
new PriorityQueue((a, b) -> Long.compare(a.executeTime, b.executeTime));
scheduler.offer(new ScheduledTask("备份数据", System.currentTimeMillis() + 10000));
scheduler.offer(new ScheduledTask("检查更新", System.currentTimeMillis() + 5000));
scheduler.offer(new ScheduledTask("心跳上报", System.currentTimeMillis() + 2000));
// 模拟调度执行
while (!scheduler.isEmpty()) {
ScheduledTask task = scheduler.poll();
System.out.println("执行: " + task.description);
}
基本上就这些。PriorityQueue适合轻量级优先任务管理,注意线程不安全,高并发下应使用 PriorityBlockingQueue。掌握好比较逻辑和数据结构设计,就能高效处理优先级任务。










