2

I have two simple POJOs:

public class Parent {
    String name;
    List<Child> children = new ArrayList<>();
    void addChild(Integer age) { children.add(new Child(age)); }
}

public class Child {
    Integer age;
}

Then I generate some data, I add for parent 100 children:

List<Parent> parentList = new ArrayList<>();

Parent first = new Parent("first");
for (int i = 0; i < 100; ++i) { first.addChild(i); }
parentList.add(first);

My goal is to remove all children younger than ten:

parentList.stream().forEach(parent -> {
    parent.setChildren(getChildrenOlderThan(parent));
});

List<Child> getChildrenOlderThan10(Parent parent) {
    return parent.getChildren().stream()
        .filter(child -> child.getAge() > 10)
        .collect(Collectors.toList());
}

Finally I have list children older than ten. But I do not want to write a separate method getChildrenOlderThan.

How to get all parents with list chilrden older than ten using only the single stream?

3 Answers 3

6

There is nice method Collection.removeIf(Predicate<? super E> filter) method.

For example:

class Example {

    public static void main(String[] args){

        List<Parent> parentList = new ArrayList<>();

        // init parents with children

        parentList.forEach(parent -> 
             parent.getChildren().removeIf(Example::childOlderThan10)
        );

    }

    static boolean childOlderThan10(Child child) {
        return child != null && child.getAge() > 10;
    }
}

See more: Method references, Collection.stream().forEach() vs Collection.forEach()?

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

2 Comments

Make sure parent.getChildren() returns a copy of the list in parent or the list of children inside your parent object will have changed.
@WimDeblauwe If parent.getChildren() returns a copy than this cope won't do anything.
1

You may inline the method getChildreanOlderThan like this:

parentList.stream().forEach(parent -> {
    parent.setChilds(parent.getChildren().stream()
            .filter(child -> child.getAge() > 10)
            .collect(Collectors.toList()));
    });

3 Comments

Sure, it will work. But some suggestions: stream() on parentList is useless here, This kind of filtering is harder to read and maintain.
@Andrii I as well like your solution more than mine. But could you explain why the stream() on parentList is useless? Does it not fulfill the goal? Do I have a bug in the implementation?
0

You can get the list of child > 10 using Flatmap

List < Child > childList = parentList.stream().flatMap(par - > par.getChildren().stream())
    .filter(child - > child.age > 10).collect(Collectors.toList());

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.