Java优先队列(PriorityQueue)完全指南:从入门到源码剖析
1. 什么是优先队列?
- 元素具有优先级,按优先级顺序出队
- 不是先进先出(FIFO)的数据结构
- 通常用堆(Heap)数据结构实现
2. Java中的PriorityQueue类
2.1 核心特性
- 基于优先级堆(最小堆)实现
- 不允许null元素
- 非线程安全
- 插入和删除操作的时间复杂度为O(log n)
2.2 构造方法
import java.util.*;
public class PriorityQueueBasics {
public static void main(String[] args) {
// 1. 默认构造方法 - 自然顺序(最小堆)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// 2. 指定初始容量
PriorityQueue<Integer> pqWithCapacity = new PriorityQueue<>(20);
// 3. 使用比较器自定义排序
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
// 4. 从其他集合初始化
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
PriorityQueue<Integer> pqFromCollection = new PriorityQueue<>(numbers);
System.out.println("默认优先队列(最小堆):");
testPriorityQueue(minHeap);
System.out.println("\n最大堆优先队列:");
testPriorityQueue(maxHeap);
}
private static void testPriorityQueue(PriorityQueue<Integer> pq) {
pq.add(5);
pq.add(2);
pq.add(8);
pq.add(1);
pq.add(9);
while (!pq.isEmpty()) {
System.out.print(pq.poll() + " ");
}
System.out.println();
}
}
运行结果:
默认优先队列(最小堆):
1 2 5 8 9
最大堆优先队列:
9 8 5 2 1
3. 核心方法详解
3.1 基本操作
public static void main(String[] args) {
PriorityQueue<String> pq = new PriorityQueue<>();
// 添加元素
pq.add("orange");
pq.offer("apple");
pq.add("banana");
pq.offer("grape");
System.out.println("优先队列内容: " + pq);
System.out.println("队列大小: " + pq.size());
// 查看队首元素(不删除)
System.out.println("队首元素: " + pq.peek());
// 删除并返回队首元素
System.out.println("出队: " + pq.poll());
System.out.println("出队后: " + pq);
// 删除指定元素
boolean removed = pq.remove("banana");
System.out.println("删除banana: " + removed);
System.out.println("删除后: " + pq);
// 清空队列
pq.clear();
System.out.println("清空后是否为空: " + pq.isEmpty());
}
}
3.2 遍历方式
public static void main(String[] args) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.addAll(Arrays.asList(10, 5, 15, 3, 7));
System.out.println("=== 不同遍历方式 ===");
// 方法1: 迭代器(不按优先级顺序)
System.out.println("使用迭代器遍历:");
Iterator<Integer> iterator = pq.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
// 方法2: for-each循环(不按优先级顺序)
System.out.println("for-each遍历:");
for (Integer num : pq) {
System.out.print(num + " ");
}
System.out.println();
// 方法3: 按优先级顺序遍历(使用poll)
System.out.println("按优先级顺序遍历:");
PriorityQueue<Integer> tempPq = new PriorityQueue<>(pq);
while (!tempPq.isEmpty()) {
System.out.print(tempPq.poll() + " ");
}
System.out.println();
}
}
4. 自定义比较器
4.1 自定义对象排序
class Student {
private String name;
private int grade;
public Student(String name, int grade) {
this.name = name;
this.grade = grade;
}
public String getName() { return name; }
public int getGrade() { return grade; }
@Override
public String toString() {
return name + "(" + grade + ")";
}
}
public class CustomComparatorExample {
public static void main(String[] args) {
// 按成绩降序排列
PriorityQueue<Student> pqByGrade = new PriorityQueue<>(
(s1, s2) -> s2.getGrade() - s1.getGrade()
);
// 按姓名升序排列
PriorityQueue<Student> pqByName = new PriorityQueue<>(
Comparator.comparing(Student::getName)
);
// 添加学生
pqByGrade.add(new Student("Alice", 85));
pqByGrade.add(new Student("Bob", 92));
pqByGrade.add(new Student("Charlie", 78));
pqByGrade.add(new Student("Diana", 95));
pqByName.addAll(pqByGrade);
System.out.println("按成绩排序:");
while (!pqByGrade.isEmpty()) {
System.out.println(pqByGrade.poll());
}
System.out.println("\n按姓名排序:");
while (!pqByName.isEmpty()) {
System.out.println(pqByName.poll());
}
}
}
4.2 复杂比较逻辑
class Task {
enum Priority { HIGH, MEDIUM, LOW }
private String name;
private Priority priority;
private int duration; // 分钟


1338

被折叠的 条评论
为什么被折叠?



