我正在学习Java Streams并随着了解的深入而发现新东西。我找到的其中一件新事物是peek()
函数。几乎所有我读到的有关peek()的内容都说它应该用于调试你的Streams。
如果我有一个Stream,其中每个账户都有用户名、密码字段以及login()和loggedIn()方法。
我也有
Consumer<Account> login = account -> account.login();
和
Predicate<Account> loggedIn = account -> account.loggedIn();
为什么这会是件糟糕的事情呢?
List<Account> accounts; //assume it's been setup
List<Account> loggedInAccount =
accounts.stream()
.peek(login)
.filter(loggedIn)
.collect(Collectors.toList());
据我所知,这段代码完全实现了它的预期功能。它:
- 获取账户列表
- 尝试登录每个账户
- 过滤掉未登录的任何账户
- 将已登录的账户收集到一个新列表中
这样做有什么缺点吗?有没有任何不应该继续进行的原因?最后,如果不使用这种解决方案,则使用什么其他解决方案?
原始版本使用.filter()方法如下:
.filter(account -> {
account.login();
return account.loggedIn();
})
forEach
可能是你想要的操作,而不是peek
。仅仅因为它在 API 中存在并不意味着它不能被滥用(比如Optional.of
)。 - Makoto.peek(Account::login)
和.filter(Account::loggedIn)
;没有理由编写一个只调用另一个方法的 Consumer 和 Predicate。 - Joshua TaylorforEach()
和peek()
)只能通过副作用进行操作;这些应该小心使用。”我的评论更多是为了提醒不要用map()
或filter()
等其他操作来替换设计用于调试目的的peek
操作。 - Didier L