Czytam o strumieniach Java i odkrywam nowe rzeczy w trakcie. Jedną z nowych rzeczy, które znalazłem, była peek()
funkcja. Prawie wszystko, co przeczytałem w Peek, mówi, że powinno się go używać do debugowania strumieni.
Co by było, gdybym miał Stream, w którym każde konto ma nazwę użytkownika, pole hasła oraz metodę login () i loggedIn ().
też mam
Consumer<Account> login = account -> account.login();
i
Predicate<Account> loggedIn = account -> account.loggedIn();
Dlaczego to miałoby być takie złe?
List<Account> accounts; //assume it's been setup
List<Account> loggedInAccount =
accounts.stream()
.peek(login)
.filter(loggedIn)
.collect(Collectors.toList());
O ile wiem, robi dokładnie to, co jest przeznaczone. To;
- Pobiera listę kont
- Próbuje zalogować się na każde konto
- Filtruje konta, które nie są zalogowane
- Zbiera zalogowane konta na nową listę
Jakie są wady zrobienia czegoś takiego? Jest jakiś powód, dla którego nie powinienem kontynuować? Wreszcie, jeśli nie to rozwiązanie, to co?
Oryginalna wersja tego używała metody .filter () w następujący sposób;
.filter(account -> {
account.login();
return account.loggedIn();
})
forEach
może to być operacja, której chcesz, a nie inną peek
. To, że jest w API, nie oznacza, że nie jest otwarte na nadużycia (np Optional.of
.).
.peek(Account::login)
i .filter(Account::loggedIn)
; nie ma powodu, aby pisać konsumenta i predykatu, który po prostu wywołuje inną taką metodę.
forEach()
i peek()
, może działać jedynie poprzez efekty uboczne; należy ich używać ostrożnie. ”. Moja uwaga była raczej przypomnieniem, że peek
operacja (która jest przeznaczona do debugowania) nie powinna być zastępowana przez robienie tego samego w ramach innej operacji, takiej jak map()
lub filter()
.