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

如何对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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:43:12