Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture the List of removed items from Java 8 Stream filtering?

I am using the following expression to filter a list of people whose birthday matches criteria.

List<Person> matchingPeople = people.stream()
.filter(p -> dateFilters.stream()
    .anyMatch(df -> 
       numOfDaysBetween(p.getBirthDate(), df.getDate())  < df.getDiffRange()
    )
)
.collect(Collectors.toList());

Collectors.toList() returns the list of people matching the criteria. I am wondering how to capture the list of people that got removed for debugging/logging purpose. One possible way is to run the list through another filter, but that will be inefficient. Can we do it in the same filter ?

like image 284
javakurious Avatar asked Aug 08 '16 17:08

javakurious


1 Answers

Yes, you can do it in the same filter call :

 List<Person> matchingPeople = 
     people.stream()
           .filter(p -> {
              if (dateFilters.stream()
                             .anyMatch(df -> numOfDaysBetween(p.getBirthDate(), df.getDate()) < df.getDiffRange()
)) 
              {
                  return true;
              } else {
                  //you can add here code to log elements that don't pass the filter
                  //or you can add these elements to an external List
                  return false;
              }
          })
          .collect(Collectors.toList());

Another alternative is to partition the input List into two Lists based on the filter predicate :

Map<Boolean, List<Person>> partition =
     people.stream()
           .collect(Collectors.partitioningBy(p -> <same code as in your filter method call>));
like image 152
Eran Avatar answered Oct 08 '22 02:10

Eran