10

Consider a Parent class with the attributes attrib1, attrib2 and List<Child> child with its corresponding getters and setters.

The Child is another class with five attributes attrib1-attrib5 with its corresponding getters and setters.

Now I created a List<Parent> parent. Then I want to filter out a List<Parent> with following condition:- Child.Attrib1 > 10;

So I created the following query by Java 8 streams.

parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c.getAttrib1() > 10));

But the problem is I will get all the child in each Parent object. Here I want to get only those child object in List<Child> that obeys the given condition.

How should I remove all the child objects in List that doesn't obeys the condition and get the new List.

0

3 Answers 3

8

What you need is a Stream<Child> if you want to receive all children. The following expression might do the trick:

parents.stream().flatMap(e -> e.getChildren().stream()).filter(c -> c.getAttrib1() > 10)

This should return all children of all parents in the list where the get attribute value is greater than 10.

If you want to update the parents list by removing all child elements that fail a condition, you can do the following:

parents.forEach(p -> p.getChildren().removeIf(c -> c.getAttrib1() > 10));

This doesn't create a new list. Instead it updates the parents list itself.

Sign up to request clarification or add additional context in comments.

6 Comments

By flatmap , how will I get filtered list of List<Parent>
As I understood your requirement is to find all children in the parents list where getAttrib1() > 10. Where does List<Parent> comes into picture? The flatMap is merging all children streams in the parent objects into a single Child stream.
My requirement is that I should remove all the child objects in List<Child> that doesn't obeys the condition and get the new List<Parent>.
A different question altogether :(. Updating the answer.
parents.removeIf removes the Parent objects from the list (not the child objects that match from the Child list). Is that what you want?
|
2

As I can understand you should add additional filter for child lists:

 parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c.getAttrib1() > 10)).forEach(e -> e.setChild(e.getChild().stream().filter(c -> c.getAttrib1 > 10).collect(toList())))

If you have not setChild:

  • You can remove items from lists
  • Create completly new parent objects

To remove you can use iterator:

parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c.getAttrib1 > 10))
   .forEach(e -> {
      for(Iterator<Child> it = e.getChild().iterator(); it.hasNext();){
          Child cur = it.next();
          if(cur.getAttrib1() <= 10) it.remove();
    }
})

1 Comment

@ sibnick: if there is no setChild, There is any way to achieve this.
1

I know the question is almost 2 years old, but hopefully this answer can help someone.

There's a library called com.coopstools.cachemonads. It extends the java stream (and Optional) classes to allow caching of entities for later use.

The solution can be found with:

List<Parent> goodParents = CacheStream.of(parents)
            .cache()
            .map(Parent::getChildren)
            .flatMap(Collection::stream)
            .map(Child::getAttrib1)
            .filter(att -> att > 10)
            .load()
            .distinct()
            .collect(Collectors.toList());

where, parents is an array or stream.

For clarity, the cache method is what stores the parents; and the load method is what pulls the parents back out. And If a parent does not have children, a filter will be needed after the first map to remove the null lists.

This library can be used in any situation where operations need to be performed on children, including map/sort/filter/etc, but where an older entity is still needed.

The code can be found at https://github.com/coopstools/cachemonads (where I've included your example in the readme), or can be downloaded from maven:

<dependency>
    <groupId>com.coopstools</groupId>
    <artifactId>cachemonads</artifactId>
    <version>0.2.0</version>
</dependency>

(or, gradle, com.coopstools:cachemonads:0.2.0)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.