在Java流中,窥视真的只是为了调试吗? [英] In Java streams is peek really only for debugging?

查看:144
本文介绍了在Java流中,窥视真的只是为了调试吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读有关Java流和发现新事物的内容。我找到的新东西之一是 peek()函数。几乎所有我读过的内容都说它应该用来调试你的Streams。

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.

如果我有一个Stream,每个帐户都有一个用户名,密码字段和一个login()和loggedIn()方法。

What if I had a Stream where each Account has a username, password field and a login() and loggedIn() method.

我还有

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

现在据我所知,这完全符合它的目的。它;

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?

这个的原始版本使用.filter()方法如下;

The original version of this used the .filter() method as follows;

.filter(account -> {
        account.login();
        return account.loggedIn();
    })


推荐答案

关键点:

不要以非预期的方式使用API​​,即使它实现了您的直接目标。这种方法将来可能会中断,未来的维护人员也不清楚。

Don't use the API in an unintended way, even if it accomplishes your immediate goal. That approach may break in the future, and it is also unclear to future maintainers.

将此分解为多个操作没有任何害处,因为它们是不同的操作。 以不明确和无意的方式使用API​​会造成损害,如果在将来的Java版本中修改此特定行为,可能会产生影响。

There is no harm in breaking this out to multiple operations, as they are distinct operations. There is harm in using the API in an unclear and unintended way, which may have ramifications if this particular behavior is modified in future versions of Java.

对此操作使用 forEach 会使维护者明白 c 意图的副作用> accounts ,并且你正在执行一些可以改变它的操作。

Using forEach on this operation would make it clear to the maintainer that there is an intended side effect on each element of accounts, and that you are performing some operation that can mutate it.

peek 是一个中间操作,在终端操作运行之前不会对整个集合进行操作,但是 forEach 确实是一个终端操作。这样,您可以围绕行为和代码流进行强有力的论证,而不是询问 peek 是否与 forEach相同的问题在此上下文中。

It's also more conventional in the sense that peek is an intermediate operation which doesn't operate on the entire collection until the terminal operation runs, but forEach is indeed a terminal operation. This way, you can make strong arguments around the behavior and the flow of your code as opposed to asking questions about if peek would behave the same as forEach does in this context.

accounts.forEach(a -> a.login());
List<Account> loggedInAccounts = accounts.stream()
                                         .filter(Account::loggedIn)
                                         .collect(Collectors.toList());

这篇关于在Java流中,窥视真的只是为了调试吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆