[英]Group by a Collection attribute using Java Streams
我有一个包含字符串集合的对象,比方说一个人说的语言。
public class Person {
private String name;
private int age;
private List<String> languagesSpoken;
// ...
}
现在,创建像这样的一些实例......
Person p1 = new Person("Bob", 21, Arrays.asList("English", "French", "German"));
Person p2 = new Person("Alice", 33, Arrays.asList("English", "Chinese", "Spanish"));
Person p3 = new Person("Joe", 43, Arrays.asList("English", "Dutch", "Spanish", "German"));
//put them in list
List<Person> people = Arrays.asList(p1,p2,p3);
...我想要的是一个Map<String, List<Person>>
,用于列出说该语言的人的每种语言:
["English" -> [p1, p2, p3],
"German" -> [p1, p3],
etc. ]
当然,这可以通过命令式方式轻松编程,但如何使用Java Streams实现功能? 我尝试了像people.stream.collect(groupingBy(Person::getLanguagesSpoken))
但那当然给了我一个Map<List<String>, List<Person>>
。 我能找到的所有例子都是使用groupingBy
on Primitives或Strings。
您可以将Person
实例分解为成对的语言和Person
(使用flatMap
),然后根据需要对它们进行分组:
Map<String, List<Person>> langPersons =
people.stream()
.flatMap(p -> p.getLanguagesSpoken()
.stream()
.map(l -> new SimpleEntry<>(l,p)))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())));
这也可以不使用流,仍然使用java-8新功能。
people.forEach(x -> {
x.getLanguagesSpoken().forEach(lang -> {
langPersons.computeIfAbsent(lang, ignoreMe -> new ArrayList<>()).add(x);
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.