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()));
它确实可以通过技能名称进行分组(但只是技能对象),但是由于flatMap的原因,失去了对Person的引用。
我想如果你先将你的 "技能 "和 "人名 "转换为 "人名",会更容易实现。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.
}
你可以创建 地图.条目 对象的每一个 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())));