class Person {
String personName;
List<Skill> skills;
}
class Skill {
String skillName;
}如何获得一张地图
约翰有绘画技巧,功夫。詹姆斯有烹饪,空手道,功夫,克里斯有绘画,远足。
输出
painting -> John, Chris
kungfu -> John, James
cooking -> James
karate -> James
hiking -> Chris我试过的是:
list.stream().collect(Collectors.groupingBy(e -> e.skills.stream(), Collectors.toSet()))我知道这不起作用,因为您不能按e.skills.stream()进行分组。
list.stream().flatMap(e -> e.skills.stream()).collect(Collectors.groupingBy(e -> e.skillName, Collectors.toSet()));它根据skillName进行分组(但只有技能对象),但是由于flatMap而丢失了对Person的引用。
发布于 2020-05-12 03:18:12
我认为,如果您首先将List<Person>转换为Stream<PersonNameSkill>,那么这将更容易实现,其中PersonNameSkill表示一个包含Person名称的标称元组,以及一个归属于它的单一Skill。
在Java 14中,您可以利用record创建这个标称的元组:
record PersonNameSkill(String personName, String skillName) {}既然存在这种情况,就可以编写一个解决方案(Java 8+):
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:
public class PersonNameSkill {
private final String personName;
private final String skillName;
// Constructor, getters, equals, hashCode, etc.
}发布于 2020-05-12 03:39:26
您可以为每个Map.Entry组合创建Skill_name->Person_name对象,然后使用Collectors.groupingBy对人名进行技能分组。
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())));https://stackoverflow.com/questions/61743020
复制相似问题