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

如何按值排序Map,值相同时按键排序?我的代码输出不符合预期

按值排序Map,值相同时按键排序的问题

问题场景

我需要实现按值排序Map,当多个条目的值相同时,再按键进行排序,但实际输出与预期不符。

测试代码

Map<PassengerType,Integer> test=new HashMap<>();
test.put(PassengerType.SENIOR_CITIZEN,1);
test.put(PassengerType.KID,1);
test.put(PassengerType.ADULT,1);

List<Map.Entry<PassengerType, Integer>> list =
        new ArrayList<Map.Entry<PassengerType, Integer>>(test.entrySet());

Collections.sort(list, new ValueThenKeyComparator());

list.stream().forEach(System.out::println);

自定义Comparator代码

public class ValueThenKeyComparator implements Comparator<Map.Entry<PassengerType, Integer>> {

    public int compare(Map.Entry<PassengerType, Integer> a, Map.Entry<PassengerType, Integer> b) {
        //System.out.println(a.getValue()+" || "+b.getValue()+" :::"+a.getValue().compareTo(b.getValue()));
        int valueCompare=a.getValue().compareTo(b.getValue());
        if(valueCompare!=0){
            return valueCompare;
        }else{
           // System.out.println(a.getKey()+" || "+b.getKey()+" :::"+a.getKey().compareTo(b.getKey()));
            return a.getKey().compareTo(b.getKey());
        }
    }

}

预期输出

ADULT=1
KID=1
SENIOR_CITIZEN=1

实际输出

KID=1
ADULT=1
SENIOR_CITIZEN=1

问题原因及解决方法

问题出在PassengerType枚举的自然排序逻辑上。你的Comparator逻辑本身是正确的——先按值比较,值相同则按键的自然顺序排序,但实际输出不符合预期,说明PassengerType枚举默认的compareTo方法(基于枚举的声明顺序)和你期望的字母顺序不一致。

比如如果你的PassengerType枚举声明顺序是:

public enum PassengerType {
    KID, ADULT, SENIOR_CITIZEN;
}

默认的compareTo会遵循这个声明顺序排序,导致KID排在ADULT前面,和预期的字母顺序不符。

有两种解决方式:

  1. 调整枚举声明顺序,按照你期望的排序顺序声明:
public enum PassengerType {
    ADULT, KID, SENIOR_CITIZEN;
}

这样默认的compareTo逻辑就会符合预期顺序。

  1. 修改Comparator的按键比较逻辑,直接按枚举名称的字母顺序比较:
    把Comparator中按键比较的代码替换为字符串比较,不受枚举声明顺序影响:
return a.getKey().name().compareTo(b.getKey().name());

这样不管枚举声明顺序如何,都会按照枚举常量的字母顺序排序,确保输出符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 22:27:20