priorityqueue.peek()以o(1)时间获取队列头部元素而不移除,返回最小(默认)或最大(自定义comparator)元素,空队列时返回null或抛异常,不改变队列结构。

PriorityQueue.peek() 是 Java 中获取优先队列头部元素(即当前优先级最高项)而不移除它的标准方法。它时间复杂度为 O(1),是安全、高效地“预览”队列顶端的首选操作。
peek() 的核心行为与前提
PriorityQueue 默认按自然顺序(升序)排列,因此 peek() 返回的是最小元素(即“优先级最高”的含义取决于你的比较逻辑)。若使用自定义 Comparator 构建最大堆,则 peek() 返回最大元素。
- 队列为空时调用 peek() 返回 null(对于引用类型)或抛出 NoSuchElementException(对原始类型包装类无影响,但注意泛型擦除下实际仍是对象)
- 该操作不改变队列结构,后续 poll() 或 remove() 才真正取出并调整堆
- peek() 不触发任何堆重排,纯粹是访问内部数组索引 0 处的元素(底层基于数组的二叉堆实现)
正确使用 peek() 的典型场景
常见于需要“先检查再决策”的逻辑,例如任务调度、事件处理、贪心算法中的候选判断:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 判断下一个待处理任务是否已超时:
if (queue.peek().getDeadline() - 合并多个有序流时,选取当前最小值而不消耗它:
int min = queue.peek().value; - 在循环中持续比较顶部元素与其他数据,仅当满足条件才 poll()
避免常见误用
不要将 peek() 和 poll() 混淆使用,尤其在空队列边界上:
- ❌ 错误:直接调用
queue.peek().doSomething()而未判空 → 可能触发 NullPointerException - ✅ 正确:先检查
if (!queue.isEmpty()) { Task t = queue.peek(); ... } - ⚠️ 注意:PriorityQueue 不是线程安全的,多线程环境下需额外同步,否则 peek() 结果可能不可靠
一个小而完整的示例
构建一个按分数降序的学生优先队列,并预览最高分学生:
PriorityQueue<student> topStudents = new PriorityQueue((a, b) -> b.score - a.score);
topStudents.offer(new Student("Alice", 95));
topStudents.offer(new Student("Bob", 87));
<p>if (!topStudents.isEmpty()) {
Student best = topStudents.peek(); // 不移除 Alice
System.out.println("当前最高分:" + best.name + " (" + best.score + ")");
// 此时队列仍含 Alice 和 Bob
}</p></student>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










