You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java PriorityQueue自定义Comparator二维数组降序排序失效问题

问题根因

你的自定义Comparator逻辑本身没有错误,问题出在对PriorityQueue的底层结构和特性的认知偏差:

  • Java中PriorityQueue的底层实现是优先级堆,不是按顺序排列的线性有序列表。你配置的降序逻辑会让它成为一个大顶堆,堆结构只需要保证堆顶元素(即调用peek()/poll()获取的第一个元素)是整个队列中优先级最高的元素,不需要保证队列内所有元素的存储顺序完全符合排序规则。
  • 你观察到的存储顺序{6,5}, {1,2}, {3,4}完全符合大顶堆的约束:堆顶是平方和最大的(6,5)(平方和61),它的两个子节点是(1,2)(平方和5)、(3,4)(平方和25),父节点的优先级都高于子节点,堆结构是合法的。堆结构中同一层的兄弟节点之间没有强制顺序要求,所以(1,2)排在(3,4)前面不属于错误。
正确的验证方式

不要直接遍历队列内部存储、或者打印队列对象来判断排序是否正确,堆的内部存储顺序本身就不是全有序的。你需要循环调用poll()方法逐个弹出堆顶元素,得到的出队顺序一定是{6,5} -> {3,4} -> {1,2},完全符合你预期的降序要求。

代码优化建议

你当前计算平方和的写法用了Math.pow()做浮点运算再强转为整数,存在浮点精度损耗的潜在风险,且运算效率更低,建议直接用整数乘法计算平方值:

int[][] a = {{1,2},{6,5},{3,4}};
PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
        int s1 = o1[0] * o1[0] + o1[1] * o1[1];
        int s2 = o2[0] * o2[0] + o2[1] * o2[1];
        return Integer.compare(s2, s1);
    }
});

注意:比较整数大小时不要用return s2 - s1这类减法写法,整数溢出时会返回错误的比较结果,Integer.compare()是安全的标准写法。

内容的提问来源于stack exchange,提问作者user2000189

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 09:54:26