问题
I am grouping and partioning a stream as follows:
// Partioning
Map<Boolean, List<Person>> partitioned = persons.stream().
collect(Collectors.partitioningBy(p -> p.getAge() > 20));
// Grouping
Map<String, List<Person>> grouped = persons.stream()
.collect(Collectors.groupingBy(p -> p.getCity()));
Is there a way i can combine both of these? I tried combining both with using groupingBy inside partioningBy, but did not get the things right. Any suggestion?
The expected result is the partition the persons with those whose name starts with P and group them by age. Here is the persons list:
List<Person> persons = Arrays.asList(
new Person("Max", 18),
new Person("Peter", 23),
new Person("Pamela", 23),
new Person("David", 12),
new Person("Pam", 12));
回答1:
I tried the following and somhow it worked.
Map<Boolean, Map<Object, List<Person>>> rr = persons.stream()
.collect(Collectors.partitioningBy(p -> p.name.startsWith("P"),
Collectors.groupingBy(p -> p.age > 20)));
The output was as expected
rr = {false={false=[Max, David]}, true={false=[Pam], true=[Peter, Pamela]}}
But, i am not sure is it the efficient way to do this. Any suggestions?
回答2:
expected result is the partition the persons with those whose name starts with P and group them by age
From the question, what seems like is that you don't need to perform a conditional check within groupingBy
as:
Map<Boolean, Map<Integer, List<String>>> rr = persons.stream()
.collect(Collectors.partitioningBy(p -> p.getName().startsWith("P"),
Collectors.groupingBy(Person::getAge,
// just for printing the output below
Collectors.mapping(Person::getName, Collectors.toList()))));
This would result given your input into:
{false={18=[Max], 12=[David]}, true={23=[Peter, Pamela], 12=[Pam]}}
^ ^
partitioned (startsWith P) grouped by(age)
来源:https://stackoverflow.com/questions/40972497/can-i-partition-a-stream-combining-with-the-grouping-by-functionality