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

如何按爱好分组拥有多个爱好的Student对象?

按爱好对学生分组的正确实现方式

嗨,我来帮你搞定这个分组问题~首先得先理清你当前代码的问题:你用s.getHobbies().stream()作为groupingBy的分组键,这相当于把每个学生映射成一个Stream对象作为分组依据,而不是单个爱好。Stream实例是唯一的,所以每个学生都会被分到单独的组里,这显然不是你想要的结果。

要实现按每个爱好分组(同一个爱好的学生归为一组),咱们需要先把每个学生和他的每个爱好一一对应起来,这时候就得用flatMap展开学生的爱好列表,再进行分组。

正确代码示例

List<Student> data = StudentData.getData();
Map<String, List<Student>> studentsByHobby = data.stream()
    // 把每个学生拆成多个「爱好-学生」的键值对条目
    .flatMap(student -> student.getHobbies().stream()
        .map(hobby -> new AbstractMap.SimpleEntry<>(hobby, student)))
    // 按爱好分组,收集对应的学生列表
    .collect(Collectors.groupingBy(
        AbstractMap.SimpleEntry::getKey,
        Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList())
    ));

代码逻辑解释

  1. flatMap展开条目:通过flatMap将每个学生的爱好列表拆分成多个独立条目——一个学生如果有3个爱好,就会变成3个「爱好+学生」的键值对,这样每个爱好都能关联到对应的学生。
  2. 分组收集结果:用groupingBy按爱好(键值对的key)分组,再通过mapping提取出每个条目的学生对象,最后收集成List<Student>,得到「爱好→对应学生列表」的映射。

Java 9+ 简化写法

如果你用的是Java 9及以上版本,可以用Collectors.flatMapping简化代码,不需要手动创建键值对:

Map<String, List<Student>> studentsByHobby = data.stream()
    .collect(Collectors.flatMapping(
        student -> student.getHobbies().stream()
            .map(hobby -> new AbstractMap.SimpleEntry<>(hobby, student)),
        Collectors.groupingBy(AbstractMap.SimpleEntry::getKey, Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList()))
    ));

不过第一种写法逻辑更直白,新手也更容易理解。

结果验证

比如爱好football对应的分组会包含学生a1、a2、a4、a8、a11,完全符合你提供的数据源情况。

内容的提问来源于stack exchange,提问作者Learn Hadoop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:28:54