2016-08-08 14 views
5

Używam tego wyrażenia do filtrowania listy osób, których kryteria spełniają kryteria urodzin.Jak przechwycić listę usuniętych elementów z Java 8 Filtrowanie strumienia?

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

Collectors.toList() zwraca listę osób spełniających kryteria. Zastanawiam się, jak zdobyć listę osób, które zostały usunięte w celu debugowania/rejestrowania. Jednym z możliwych sposobów jest uruchomienie listy przez inny filtr, ale to będzie nieefektywne. Czy możemy zrobić to w tym samym filtrze?

+2

Cóż, jeśli nie chcesz filtrować żadnych elementów ou t, możesz po prostu mapować, grupować według wyniku i redukować na dwie różne listy wyników. – midor

Odpowiedz

6

Tak, można to zrobić w tym samym filter rozmowy:

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()); 

Inną alternatywą jest podzielić listę wejściową na dwie listy na podstawie orzeczenia filtr:

Map<Boolean, List<Person>> partition = 
    people.stream() 
      .collect(Collectors.partitioningBy(p -> <same code as in your filter method call>)); 
+0

Alternatywa jest bardzo fajna! Dzięki! – javakurious

0

można po prostu usuwaj pasujące osoby z kolekcji:

people.removeAll(matchingPeople); 
+1

Takie podejście może stać się naprawdę mylące, ponieważ zmienia stan oryginalnej kolekcji - używaj ostrożnie/ostrożnie/jeszcze lepiej, ale wcale. – Bwvolleyball

Powiązane problemy