猿问

在Java流中,PEEK真的只用于调试吗?

在Java流中,PEEK真的只用于调试吗?

我正在阅读有关Java流的内容,并在进行过程中发现新的东西。我发现的新发现之一是peek()功能。我在peek上读到的几乎所有东西都说它应该用来调试您的流。

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

我也有

Consumer<Account> login = account -> account.login();

Predicate<Account> loggedIn = account -> account.loggedIn();

为什么会这么糟?

List<Account> accounts; //assume it's been setupList<Account> loggedInAccount = accounts.stream()
    .peek(login)
    .filter(loggedIn)
    .collect(Collectors.toList());

据我所知,这完全是它想要做的。它;

  • 接受一个帐户列表
  • 尝试登录到每个帐户
  • 过滤掉任何未登录的帐户
  • 将登录帐户收集到新列表中。

做这种事有什么坏处?有什么理由不让我继续吗?最后,如果不是这个解决方案,那又是什么呢?

最初的版本使用了.filter()方法,如下所示;

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


达令说
浏览 724回答 3
3回答

慕娘9325324

其中的关键是:不要以意外的方式使用API,即使它实现了您的直接目标。这种方法将来可能会中断,而且对未来的维护人员来说也是不清楚的。将其分解为多个操作是无害的,因为它们是不同的操作。那里是以一种不明确和意外的方式使用API的危害,如果这种特定的行为在Java的未来版本中被修改,可能会产生影响。使用forEach在此操作中,将向维护人员清楚地表明预定的每一个元素的副作用accounts,并且您正在执行一些可以使其发生变异的操作。从某种意义上讲,这也是比较传统的peek是一个中间操作,在终端操作运行之前不会对整个集合进行操作,但是forEach确实是终点站。这样,您就可以围绕您的行为和代码流提出强有力的论点,而不是问有关以下问题的问题:peek会表现得和forEach在这种情况下。accounts.forEach(a&nbsp;->&nbsp;a.login());List<Account>&nbsp;loggedInAccounts&nbsp;=&nbsp;accounts.stream() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(Account::loggedIn) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());

梦里花落0921

也许经验法则应该是,如果您确实在“调试”场景之外使用了peek,那么只有在确定终止和中间过滤条件是什么的情况下,才应该这样做。例如:return&nbsp;list.stream().map(foo->foo.getBar()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.peek(bar->bar.publish("HELLO")) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());在您想要的情况下,似乎是一个有效的情况,在一个操作中,将所有foos转换为条形图,并向他们问好。看起来比这样更有效率和优雅:List<Bar>&nbsp;bars&nbsp;=&nbsp;list.stream().map(foo->foo.getBar()).collect(Collectors.toList());bars.forEach(bar->bar.publish("HELLO"));return&nbsp;bars;而且你不会重复一个集合两次。
随时随地看视频慕课网APP

相关分类

Java
我要回答