如何按爱好分组拥有多个爱好的Student对象?
按爱好对学生分组的正确实现方式
嗨,我来帮你搞定这个分组问题~首先得先理清你当前代码的问题:你用s.getHobbies().stream()作为groupingBy的分组键,这相当于把每个学生映射成一个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()) ));
代码逻辑解释
- flatMap展开条目:通过
flatMap将每个学生的爱好列表拆分成多个独立条目——一个学生如果有3个爱好,就会变成3个「爱好+学生」的键值对,这样每个爱好都能关联到对应的学生。 - 分组收集结果:用
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
相关产品推荐
相关产品推荐

