Sto leggendo sui flussi Java e scoprendo nuove cose mentre procedo. Una delle novità che ho scoperto è stata la peek()
funzione. Quasi tutto quello che ho letto su Peek dice che dovrebbe essere usato per eseguire il debug dei tuoi stream.
E se avessi un flusso in cui ogni account ha un nome utente, un campo password e un metodo login () e loggIn ().
Ho anche
Consumer<Account> login = account -> account.login();
e
Predicate<Account> loggedIn = account -> account.loggedIn();
Perché questo sarebbe così male?
List<Account> accounts; //assume it's been setup
List<Account> loggedInAccount =
accounts.stream()
.peek(login)
.filter(loggedIn)
.collect(Collectors.toList());
Ora, per quanto posso dire, fa esattamente quello che è destinato a fare. It;
- Prende un elenco di account
- Cerca di accedere a ciascun account
- Filtra tutti gli account che non hanno effettuato l'accesso
- Raccoglie gli account registrati in un nuovo elenco
Qual è il lato negativo di fare qualcosa del genere? Qualche motivo per cui non dovrei procedere? Infine, se non questa soluzione, allora?
La versione originale di questo utilizzava il metodo .filter () come segue;
.filter(account -> {
account.login();
return account.loggedIn();
})
forEach
potrebbe essere l'operazione desiderata al contrario peek
. Solo perché è nell'API non significa che non sia aperto per abuso (come Optional.of
).
.peek(Account::login)
e .filter(Account::loggedIn)
; non c'è motivo di scrivere un consumatore e un predicato che chiama semplicemente un altro metodo del genere.
forEach()
e peek()
, può operare solo tramite effetti collaterali; questi dovrebbero essere usati con cura. ”. La mia osservazione è stata più di ricordare che l' peek
operazione (che è progettata per scopi di debug) non dovrebbe essere sostituita facendo la stessa cosa all'interno di un'altra operazione come map()
o filter()
.