Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating nested list using lambda expression : Java 8

I would like to update a list of objects inside another list using streams api.

I have a List<User> users which has List<Filter> filters. I would like to update the elements matching the userID and corresponding filterName with Filter object coming in as an argument. Map does not allow me to do it.

I tried doing the below but map does not seem to allow mapping multiple elements.

public void update(String userID, Filter filter) {
        users.stream()
        .filter(element -> element.getUserId().equals(userID)
            && element.getFilters().stream().filter(f -> f.getName().equals(filter.getName())).findAny().isPresent())
        .forEach(x -> {
            x.getFilters().stream().map(s -> {
                s.setCreatedOn(filter.getCreatedOn());
                s.setDescription(filter.getDescription());
                s.setEnabled(filter.isEnabled());
                s.setFilterValue(filter.getFilterValue());
                s.setReadOnly(filter.isReadOnly());
                s.setModifiedOn(filter.getModifiedOn());
                s.setName(filter.getName());
                s.setType(filter.getType());
                s.setValid(filter.isValid());
                s.setEncrypted(filter.isEncrypted());
                });
        });
    }

What is the method which can be used to perform update of inner List<Filter>

like image 470
wandermonk Avatar asked Nov 07 '17 08:11

wandermonk


1 Answers

Your original code can work if you replace map with forEach in x.getFilters().stream().map(, but I suggest a better alternative.

Generate a flat Stream<Filter> of all the Filters that should be updated and then run your update on them:

public void update(String userID, Filter filter) {
    users.stream()
         .filter(element -> element.getUserId().equals(userID)) // get relevant user[s]
         .flatMap(element -> element.getFilters().stream()) // get all filters of relevant 
                                                            // user[s]
         .filter(f -> f.getName().equals(filter.getName())) // keep only relevant filters
         .forEach (f -> { // run your update on all the relevant filters
              f.setCreatedOn(filter.getCreatedOn());
              f.setDescription(filter.getDescription());
              f.setEnabled(filter.isEnabled());
              f.setFilterValue(filter.getFilterValue());
              f.setReadOnly(filter.isReadOnly());
              f.setModifiedOn(filter.getModifiedOn());
              // f.setName(filter.getName()); can be removed, as commented by markusk
              f.setType(filter.getType());
              f.setValid(filter.isValid());
              f.setEncrypted(filter.isEncrypted());
            });
}
like image 186
Eran Avatar answered Oct 28 '22 06:10

Eran