Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter and collect nested collection elements using Java 8 stream

I have a collection of Parent objects and each has a collection of Child elements, for example:

public class Parent {
    private Collection<Child> children;
}

public class Child {
    private String type;
}

How would I use Java 8 functional programming to filter and collect together a collection of Child where the type is equal to 'A'?

I have attempted this with the following:

Collection<Child> filteredChildren = parents.stream()
                                        .forEach(p ->
                                            filteredChildren.addAll(p.getChildren().stream()
                                                          .filter(c -> c.getType().equals("A"))
                                                          .collect(Collectors.toList()))
                                        );

But I get the following error:

Variable 'filteredChildren' initializer 'parents.stream() .forEach(p -> ...' is redundant less... (⌘F1) This inspection points out the cases where a variable value is never used after its assignment, i.e.:  - the variable never gets read after assignment OR  - the value is always overwritten with another assignment before the next variable read OR  - the variable initializer is redundant (for one of the above two reasons)

How do I filter the nested collections by type and collect them?

like image 342
crmepham Avatar asked Jul 22 '18 10:07

crmepham


1 Answers

It's wrong to use forEach in your code for the terminal Stream operation, since it produces no output, so you can't assign it to the filteredChildren variable.

Use flatMap in order to get a flat Stream of all the Child instances (filtered by type) of all the Parent instances, and then collect to a List:

Collection<Child> filteredChildren = 
    parents.stream()
           .flatMap(p -> p.getChildren()
                          .stream()
                          .filter(c -> c.getType().equals("A")))
           .collect(Collectors.toList());
like image 116
Eran Avatar answered Oct 06 '22 00:10

Eran