Java中PriorityQueue的lambda参数(a,b)来源及最大堆实现疑问
Java PriorityQueue Lambda比较器核心问题解析
1. Lambda参数a、b的来源与求值逻辑
- a和b是PriorityQueue在调整堆结构时随机选取的两个待比较元素,没有固定的位置(不是特指堆顶或堆底元素)。当你往队列里加元素、或者取出堆顶后重构堆的时候,队列会不断调用这个比较器来确定元素间的相对位置,这时候就会把需要对比的两个元素传入lambda的a和b参数。
- 求值逻辑很直接:先通过
map.get(a)和map.get(b)分别获取两个元素在HashMap中对应的数值,然后计算map.get(b) - map.get(a)的结果,这个结果就是Comparator接口compare(a,b)方法的返回值。
2. 为什么这段代码实现的是最大堆
先明确Java Comparator的规则:
- 若
compare(a,b)返回负数:表示a的优先级高于b,a应该排在b前面 - 若返回正数:表示b的优先级高于a,b应该排在a前面
- 若返回0:两者优先级相同
你的lambda表达式是(a,b)->map.get(b)-map.get(a),拿实际场景举例:
假设元素X在map中对应的值是10,元素Y对应的值是5。当比较X和Y时:
- 如果a是Y,b是X:
map.get(b)-map.get(a) = 10-5=5>0,返回正数,说明X(b)优先级更高,会排在Y(a)前面 - 如果a是X,b是Y:
map.get(b)-map.get(a)=5-10=-5<0,返回负数,说明X(a)优先级更高,还是排在Y前面
最终的效果是:map中值越大的元素,优先级越高,会被放在堆的更上层,堆顶就是map值最大的元素,这就实现了按map值排序的最大堆。
3. a、b是否属于堆的顶部或底部元素
不是固定的。a和b只是堆在维护结构过程中需要对比的任意两个节点,可能是新插入的元素和它的父节点,也可能是堆重构时的兄弟节点,或者其他需要调整位置的节点对,没有固定的顶部/底部属性,唯一的作用就是用来判断两个元素的相对优先级顺序。
内容的提问来源于stack exchange,提问作者Namash Sharma
相关产品推荐
相关产品推荐

