Java按Team属性分组汇总分数并正确排序的问题
解决方案
你的问题出在普通HashMap不维护元素顺序,而且提前对原List排序的操作完全无效——因为groupingBy默认返回的HashMap会打乱顺序,且你需要的是汇总后的分数排序,不是原列表的排序。
正确的做法是先完成分组汇总,再对汇总结果按规则排序:
import java.util.*; import java.util.stream.Collectors; public class TeamDemo { public static void main(String[] args) { List<Team> teams = Arrays.asList( new Team("TeamA", 3), new Team("TeamB", 3), new Team("TeamA", 3), new Team("TeamC", 0), new Team("TeamB", 1), new Team("TeamD", 1), new Team("TeamE", 1) ); // 1. 分组汇总每个队伍的总分 Map<String, Integer> totalScoreMap = teams.stream() .collect(Collectors.groupingBy(Team::getName, Collectors.summingInt(Team::getScore))); // 2. 对汇总结果排序:先按总分降序,总分相同按队伍名称升序 List<Map.Entry<String, Integer>> sortedResult = totalScoreMap.entrySet().stream() .sorted( Map.Entry.<String, Integer>comparingByValue(Comparator.reverseOrder()) .thenComparing(Map.Entry.comparingByKey()) ) .collect(Collectors.toList()); // 输出验证 sortedResult.forEach(entry -> System.out.println("- " + entry.getKey() + " - " + entry.getValue())); } static class Team { private String name; private int score; public Team(String name, int score) { this.name = name; this.score = score; } public String getName() { return name; } public int getScore() { return score; } } }
关键说明
- 分组汇总:先用
groupingBy配合summingInt完成分数累加,这一步只负责数据聚合,不处理顺序。 - 排序逻辑:针对汇总后的
Map.Entry集合排序,使用comparingByValue(Comparator.reverseOrder())实现分数降序,再用thenComparing(comparingByKey())实现同分数下名称升序。 - 有序Map(可选):如果需要保留排序后的Map结构,可以将排序后的entry放入
LinkedHashMap(它会维护插入顺序):
Map<String, Integer> sortedMap = new LinkedHashMap<>(); sortedResult.forEach(entry -> sortedMap.put(entry.getKey(), entry.getValue()));
为什么原代码无效?
- 你提前对
teams排序的操作毫无意义,因为groupingBy默认返回的HashMap不保证任何顺序,会直接打乱你之前的排序结果。 - 原代码的排序逻辑是先按名称升序、再按原实例分数降序,这和你需要的汇总后分数排序完全不是一个逻辑。
内容的提问来源于stack exchange,提问作者Wion
相关产品推荐
相关产品推荐

