I'm reading up about Java streams and discovering new things as I go along. One of the new things I found was the peek()
function. Almost everything I've read on peek says it should be used to debug your Streams.
What if I had a Stream where each Account has a username, password field and a login() and loggedIn() method.
I also have
Consumer<Account> login = account -> account.login();
and
Predicate<Account> loggedIn = account -> account.loggedIn();
Why would this be so bad?
List<Account> accounts; //assume it's been setup
List<Account> loggedInAccount =
accounts.stream()
.peek(login)
.filter(loggedIn)
.collect(Collectors.toList());
Now as far as I can tell this does exactly what it's intended to do. It;
- Takes a list of accounts
- Tries to log in to each account
- Filters out any account which aren't logged in
- Collects the logged in accounts into a new list
What is the downside of doing something like this? Any reason I shouldn't proceed? Lastly, if not this solution then what?
The original version of this used the .filter() method as follows;
.filter(account -> {
account.login();
return account.loggedIn();
})
forEach
may be the operation you want as opposed topeek
. Just because it's in the API doesn't mean it's not open for abuse (likeOptional.of
). – Discommend.peek(Account::login)
and.filter(Account::loggedIn)
; there's no reason to write a Consumer and Predicate that just calls another method like that. – CompilerforEach()
andpeek()
, can operate only via side-effects; these should be used with care.”. My remark was more to remind that thepeek
operation (which is designed for debugging purposes) should not be replaced by doing the same thing inside another operation likemap()
orfilter()
. – GrandsonforEach
would be more intuitive here. We are so obsessed with java 8 streams and try to solve everything using them. I observe lot of people(including me) try to achieve something like the above usingpeek()
thought the API clearly mentions not to use it. – Mayle