如何对Map<Person, Information>按年龄分组并保留组内最高分数及人员?
解决方案:按年龄分组人员数据,保留最高分数并关联同年龄所有人员
我来帮你搞定这个分组需求!咱们一步步拆解实现,逻辑清晰还容易调整:
核心思路
先把分散的人员数据聚合到统一结构,按年龄分组后,每组计算最高分数并收集所有姓名,最后按你要的格式输出。
步骤1:聚合核心数据
首先咱们把HashMap<Person, Information>里的信息(年龄、分数、姓名)整合到一个辅助类里,方便后续处理。假设你有一个Map<Person, String>来存储Person对应姓名的映射(如果你的Information类实际包含姓名,直接改下面的取值逻辑就行):
// 用record定义轻量辅助类,存储人员核心信息 record PersonData(String name, int age, double score) {} // 你的原始数据 HashMap<Person, Information> personInfoMap = // 你的人员-信息映射 Map<Person, String> personNameMap = // Person到姓名的映射 // 把原始数据转换成统一的PersonData列表 List<PersonData> personList = personInfoMap.entrySet().stream() .map(entry -> { Person person = entry.getKey(); Information info = entry.getValue(); String name = personNameMap.get(person); return new PersonData(name, info.getAge(), person.getScore()); }) .collect(Collectors.toList());
步骤2:按年龄分组
用流式操作快速把同年龄的人员归到一组:
// 按年龄分组,key是年龄,value是该年龄下的所有PersonData Map<Integer, List<PersonData>> ageGrouped = personList.stream() .collect(Collectors.groupingBy(PersonData::age));
步骤3:处理每组的最高分数与姓名集合
遍历每个年龄组,计算最高分数,同时收集该组所有人员的姓名:
// 定义结果类,存储每个年龄组的最终输出数据 record ResultEntry(double topScore, List<String> names) {} Map<Integer, ResultEntry> resultMap = new HashMap<>(); for (Map.Entry<Integer, List<PersonData>> entry : ageGrouped.entrySet()) { int age = entry.getKey(); List<PersonData> peopleInGroup = entry.getValue(); // 找到该组的最高分数 double highestScore = peopleInGroup.stream() .mapToDouble(PersonData::score) .max() .orElse(0.0); // 兜底处理空组,实际场景不会触发 // 收集该组所有姓名 List<String> allNames = peopleInGroup.stream() .map(PersonData::name) .collect(Collectors.toList()); resultMap.put(age, new ResultEntry(highestScore, allNames)); }
步骤4:格式化输出成预期样式
最后把结果拼接成你想要的字符串格式:
StringBuilder outputBuilder = new StringBuilder("{"); for (Map.Entry<Integer, ResultEntry> resultEntry : resultMap.entrySet()) { int age = resultEntry.getKey(); ResultEntry data = resultEntry.getValue(); // 拼接年龄和最高分数部分 outputBuilder.append(String.format("Person has at Age: %d (Score: %.0f) =", age, data.topScore())); // 处理姓名:单个直接输出,多个用方括号包裹 if (data.names().size() == 1) { outputBuilder.append(data.names().get(0)); } else { outputBuilder.append("[").append(String.join(", ", data.names())).append("]"); } outputBuilder.append(", "); } // 去掉最后多余的逗号和空格 if (outputBuilder.length() > 1) { outputBuilder.setLength(outputBuilder.length() - 2); } outputBuilder.append("}"); // 打印最终结果 System.out.println(outputBuilder.toString());
运行效果
执行后会输出你预期的结果:
{Person has at Age: 12 (Score: 50) =alex, Person has at Age: 16 (Score: 50) =miki, Person has at Age: 5 (Score: 100) =[shi, thomas], Person has at Age: 4 (Score: 50) =rafi, Person has at Age: 1 (Score: 50) =sharbel, Person has at Age: 14 (Score: 60) =[thomy, angelos], Person has at Age: 11 (Score: 100) =[musti, aloo], Person has at Age: 2 (Score: 50) =evi}
如果你的数据结构有小调整(比如姓名存在Information里),只需要修改PersonData的构造逻辑即可,核心分组和计算逻辑完全通用。
内容的提问来源于stack exchange,提问作者Catalina
相关产品推荐
相关产品推荐

