Java如何实现List<Map<String,Object>>按Age、Name多级排序
问题根因
之前只能实现单级Age排序的核心原因,是编写比较器时仅提取了Age字段的比较逻辑,没有在Age值相等的分支下,追加Name字段的比较步骤——当比较器遇到Age值相同的元素时,会直接判定两个元素排序权重相等,自然不会按Name做二次调整,最终出现同Age下顺序不符合预期的问题。
实现方案
Java 的比较器支持链式串联多级排序规则,不需要手动写嵌套的判断分支,直接用内置的Comparator工具方法就能实现需求:
Java 8+ 简洁实现(推荐)
直接通过Comparator.comparing定义第一级排序规则,再用thenComparing追加第二级规则即可:
list.sort( // 第一级:按Age字段升序 Comparator.comparingInt((Map<String, Object> map) -> (Integer) map.get("Age")) // 第二级:Age相等时,按Name字段的字符串字典序升序 .thenComparing(map -> (String) map.get("Name")) );
这种写法的执行逻辑完全匹配需求:先按Age值从小到大排序,仅当两个元素的Age值完全相等时,才会触发Name字段的比较,调整同Age组内的顺序。
低版本Java兼容实现
如果项目还在使用Java 8之前的版本,可以手动实现比较器的判断分支,核心是不要遗漏Age相等场景下的Name比较:
Collections.sort(list, new Comparator<Map<String, Object>>() { @Override public int compare(Map<String, Object> o1, Map<String, Object> o2) { Integer age1 = (Integer) o1.get("Age"); Integer age2 = (Integer) o2.get("Age"); int ageCompareResult = age1.compareTo(age2); // Age不相等时直接返回排序结果 if (ageCompareResult != 0) { return ageCompareResult; } // Age相等时,再比较Name字段的字典序 String name1 = (String) o1.get("Name"); String name2 = (String) o2.get("Name"); return name1.compareTo(name2); } });
效果验证
按照上述代码执行排序后,输出结果和你给出的期望完全一致:
{Age=23, Name=Ram} {Age=23, Name=Rohan} {Age=24, Name=Sam} {Age=24, Name=Shyam} {Age=25, Name=George}
小提示:因为Map的value是Object类型,做字段值提取时要注意类型匹配,按照你给出的初始化代码,Age存的是Integer、Name存的是String,上述强转操作是完全安全的,不会触发类型转换异常。
内容的提问来源于stack exchange,提问作者Sagnik Chatterjee
相关产品推荐
相关产品推荐

