java中priorityqueue默认为小顶堆,实现大顶堆需传入自定义比较器:推荐用collections.reverseorder()或integer.compare(b, a)等安全方式,自定义类需按字段降序比较,peek()返回最大值但遍历不保证有序。

Java 中的 PriorityQueue 默认是小顶堆(最小元素在队首),要实现大顶堆,需传入自定义比较器,让较大元素优先级更高。
使用 Lambda 表达式创建大顶堆比较器
最简洁的方式是用 Lambda 实现 Comparator,对两个元素返回相反的自然顺序结果:
- 对于
Integer:用(a, b) -> b - a或更安全的Integer.compare(b, a) - 对于
String:用(s1, s2) -> s2.compareTo(s1) - 注意避免直接用
b - a处理可能溢出的整数类型,推荐用Integer.compare(b, a)
使用 Collections.reverseOrder() 快速构造
若元素类型实现了 Comparable(如 Integer、String),可直接复用其自然序的逆序:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
new PriorityQueue(Collections.reverseOrder())—— 简洁可靠 - 该方法内部已处理了 null 安全和溢出问题,比手写减法更健壮
为自定义类实现大顶堆
若元素是自定义对象(如 Person),需明确指定排序字段并反转逻辑:
- 例如按年龄降序:用
(p1, p2) -> Integer.compare(p2.getAge(), p1.getAge()) - 也可让类自身实现
Comparable,并在compareTo中返回相反逻辑,但通常建议外部传比较器,更灵活 - 若排序字段可能为 null,需额外判断,避免
NullPointerException
验证是否为大顶堆
不能仅靠 peek() 判断,因为堆结构不保证整体有序。正确验证方式:
- 插入若干元素后,连续调用
poll(),观察输出是否从大到小递减 -
peek()返回的始终是当前最大值(即堆顶),这是大顶堆的核心特征 - 注意:
PriorityQueue不提供遍历保证顺序,不要通过toArray()或增强 for 循环检查“是否排好序”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










