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

Java PriorityQueue未按预期顺序出队问题求助

Java PriorityQueue未按预期顺序出队问题求助

嗨,我发现你代码里的问题啦!导致输出顺序不符合预期的根源是包装类的引用比较错误,咱们一步步来拆解:

首先,你在Comparator的compare方法里用了a.getValue() != b.getValue()来判断两个值是否相等,这是个容易踩的坑!因为Integer是包装类,当值不在-128~127的默认缓存范围内时(比如你用的200),每次调用getValue()返回的都是新的Integer对象,!=比较的是对象引用而非实际数值。所以哪怕两个值都是200,a.getValue() != b.getValue()也会返回true,导致代码进入第一个分支:return Integer.compare(b.getValue(), a.getValue())。

而Integer.compare(200, 200)的结果是0,这会让PriorityQueue认为这两个元素的优先级完全相同。对于优先级相同的元素,PriorityQueue不会保证它们的顺序,最终出队顺序就会依赖元素的插入顺序——而HashMap的entrySet()遍历顺序是无序的(不保证和插入顺序一致),所以你才会得到[accountB(200), accountC(200), accountA(200)]这样的结果。

那怎么修复呢?把判断条件改成基于数值的比较就好啦:

  • 方法一:用!a.getValue().equals(b.getValue()),这是包装类比较值的正确方式
  • 方法二:用Integer.compare(a.getValue(), b.getValue()) != 0,直接比较数值大小

修改后的Comparator示例:

PriorityQueue<Map.Entry<String, Integer>> maxHeap = new PriorityQueue<>(new Comparator<Map.Entry<String, Integer>>() {
    @Override
    public int compare(Map.Entry<String, Integer> a, Map.Entry<String, Integer> b) {
        int valueCompare = Integer.compare(b.getValue(), a.getValue());
        if (valueCompare != 0) {
            return valueCompare;
        }
        return a.getKey().compareTo(b.getKey());
    }
});

这样修改后,当值相等时,代码会进入key的比较分支,按照key的字典序升序排列,poll出来的顺序就会是accountA(200), accountB(200), accountC(200),完全符合你的预期啦!

另外补充一点:HashMap本身是无序集合,它的entrySet遍历顺序和插入顺序无关,但PriorityQueue会严格按照你定义的Comparator对元素排序,只要Comparator逻辑正确,最终出队顺序就会符合预期。

备注:内容来源于stack exchange,提问作者laserman999

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:29:29