Search code examples
javajava-8java-streamremove-if

Remove in depth elements using streams


I have the following classes.

Class A {
    List<B> b
   //getters and setters
}

CLass B {
   List<C> c
   //getters and setters
}

 Class C {
    List<D> d
   //getters and setter
}

Class D {}

What i want to do is remove list d if a specific search term is not in the list. I have tried to do it but no luck. I think it removes but the reference is not saved.

a.stream()
        .flatMap(a-> a.getB().stream())
        .flatMap(b-> b.getC().stream())
        .map(c-> c.getD())
        .collect(Collectors.toList())
        .removeIf(list -> {
            boolean toBeRemoved = true;
            boolean containsMatch = list.stream().anyMatch(w-> {return w.getId().equalsIgnoreCase(searchTerm);});
            if(containsMatch) {
                toBeRemoved = false;
            }               
            return toBeRemoved;
        });

Can someone help me?


Solution

  • What you did builds a List<List<D>> and you remove List<D> elements that does not correponds, but that never changes the objects you have.

    • You need to iterate over all C elements,
    • You keep the ones that does not correpond (use noneMatch() to check this)
    • for these ones you replace the list by an empty one (or clear the actual c.getD().clear())

    a.stream()
        .flatMap(a-> a.getB().stream())
        .flatMap(b-> b.getC().stream())
        .filter(c -> c.getD().stream().noneMatch(w -> w.getId().equalsIgnoreCase(searchTerm)))
        .forEach(c-> c.setD(new ArrayList<>()));    // or .forEach(c-> c.getD().clear());