Java中PriorityQueue比较器语法解析:Top K高频元素大顶堆实现
解析PriorityQueue大顶堆比较器:
(a,b) -> map.get(b) - map.get(a) 先明确PriorityQueue的比较器规则
Java的PriorityQueue默认是小顶堆,它的排序逻辑完全由传入的Comparator决定,核心规则是:
- 当
compare(a, b)返回负数:a会被排在b的前面(逻辑上认为a“小于”b) - 当返回正数:
b会被排在a的前面(逻辑上认为b“小于”a) - 返回0:
a和b的顺序不做强制要求
默认小顶堆用的是自然排序,比如对整数就是(a,b) -> a - b,保证堆顶是队列中最小的元素。
拆解你的lambda比较器
在「Top K高频元素」场景中,map存储的是元素值→出现次数的映射,队列里的元素是原数组中的数字(比如Integer类型),(a,b) -> map.get(b) - map.get(a)的逻辑可以拆成这几步:
- 参数含义:
a和b是队列中正在比较的两个元素(原数组中的数字)。 - 核心计算逻辑:拿
b的出现次数减去a的出现次数,结果直接决定两者的排序位置:- 如果
b的出现次数 >a的:结果为正数 → 按照规则,b会被排在a前面(次数多的元素靠前) - 如果
b的出现次数 <a的:结果为负数 →a会被排在b前面(次数多的元素靠前) - 如果次数相等:结果为0,两者顺序随意
- 如果
为什么这是大顶堆?
大顶堆的核心特性是堆顶元素是队列中“最大”的元素,这里的“最大”指出现次数最多。
这个比较器通过反转默认小顶堆的逻辑实现了大顶堆:
- 默认小顶堆是让“更小”的元素排在前面,而我们的比较器把“出现次数更多”的元素定义为规则里的“更小”元素(比如当
a次数更多时,compare(a,b)返回负数,会让a排在前面)。 - 最终堆顶会始终是出现次数最多的元素,完全符合大顶堆的特性。
实际例子验证
假设map里的映射是:{3:5, 1:3, 2:4},队列里有元素3、1、2:
- 比较3和1:
map.get(1)-map.get(3) = 3-5 = -2(负数)→ 3排在1前面 - 比较3和2:
map.get(2)-map.get(3) =4-5=-1(负数)→3排在2前面 - 最终堆顶是3(出现次数最多的元素),完美实现大顶堆的效果。
内容的提问来源于stack exchange,提问作者Alisha
相关产品推荐
相关产品推荐

