首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8按列表中的单个元素分组

Java 8按列表中的单个元素分组
EN

Stack Overflow用户
提问于 2020-05-12 02:59:26
回答 2查看 99关注 0票数 1
代码语言:javascript
复制
class Person {
    String personName;
    List<Skill> skills;
}

class Skill {
    String skillName;
}

如何获得一张地图

  1. skillName和personName
  2. skillName和person对象

约翰有绘画技巧,功夫。詹姆斯有烹饪,空手道,功夫,克里斯有绘画,远足。

输出

代码语言:javascript
复制
painting -> John, Chris
kungfu -> John, James
cooking -> James
karate -> James
hiking -> Chris

我试过的是:

代码语言:javascript
复制
list.stream().collect(Collectors.groupingBy(e -> e.skills.stream(), Collectors.toSet()))

我知道这不起作用,因为您不能按e.skills.stream()进行分组。

代码语言:javascript
复制
list.stream().flatMap(e -> e.skills.stream()).collect(Collectors.groupingBy(e -> e.skillName, Collectors.toSet()));

它根据skillName进行分组(但只有技能对象),但是由于flatMap而丢失了对Person的引用。

EN

回答 2

Stack Overflow用户

发布于 2020-05-12 03:18:12

我认为,如果您首先将List<Person>转换为Stream<PersonNameSkill>,那么这将更容易实现,其中PersonNameSkill表示一个包含Person名称的标称元组,以及一个归属于它的单一Skill

在Java 14中,您可以利用record创建这个标称的元组:

代码语言:javascript
复制
record PersonNameSkill(String personName, String skillName) {}

既然存在这种情况,就可以编写一个解决方案(Java 8+):

代码语言:javascript
复制
list.stream().flatMap(person -> person.skills.stream()
        .map(skill -> new PersonNameSkill(person.personName, skill.skillName)))
    .collect(Collectors.groupingBy(PersonNameSkill::skillName,
        Collectors.mapping(PersonNameSkill::personName, Collectors.toSet())));

如果使用的是旧版本的Java,则可以使用以下方法创建PersonNameSkill

代码语言:javascript
复制
public class PersonNameSkill {
    private final String personName;
    private final String skillName;

    // Constructor, getters, equals, hashCode, etc.
}
票数 2
EN

Stack Overflow用户

发布于 2020-05-12 03:39:26

您可以为每个Map.Entry组合创建Skill_name->Person_name对象,然后使用Collectors.groupingBy对人名进行技能分组。

代码语言:javascript
复制
Map<String, List<String>> groupingBySkill = persons.stream()
            .flatMap(p -> p.getSkills().stream().map(Skill::getSkillName)
                    .map(sk -> new AbstractMap.SimpleEntry<String, String>(sk, p.getPersonName())))
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61743020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档