【问题标题】:Java 8 Streams API functions [closed]Java 8 Streams API 函数 [关闭]
【发布时间】:2020-06-27 13:03:18
【问题描述】:

我是 Java 8 Streams API 的新手。我正在使用forEachfilter 并注意到可以使用其中任何一个修改以下代码以产生相同的结果。那么,两者有何不同,如何决定何时使用哪个?

items.forEach(item -> {
    if (item.contains("B") {
        System.out.println(item);
    }
});
items
    .filter(item -> item.contains("B"))
    .forEach(System.out::println);

【问题讨论】:

    标签: java if-statement java-8 functional-programming java-stream


    【解决方案1】:

    它们具有相同的效果。

    不同之处在于调用filter 的代码使用流的过滤操作,而forEachif 语句使用普通的旧if 语句。

    使用哪一个取决于你要应用什么风格,但是函数式编程范式,也就是后一段代码的风格,最近变得更流行了。


    我个人会使用

    items
        .filter(item -> item.contains("B"))
        .forEach(System.out::println);
    

    因为我发现这更易读。

    【讨论】:

      【解决方案2】:

      除了可读性之外:对于第二个版本,这两个调用可以并行化,尤其是在过滤器和输出都需要一些时间的情况下。

      想象一下,过滤器检查数据库需要 5 秒的调用,而不是打印到控制台,而是将内容上传到服务器,这也需要 5 秒。

      在您的第一个版本中,流管道将需要在 forEach 调用中花费 10 秒(如果发生输出,很明显)。

      在第二个版本中,一个元素通过过滤器调用后,可以过滤另一个元素,同时输出第一个元素;这意味着整个过程只需要 15 秒,而不是本例中的 20 秒。

      【讨论】:

      • forEach 不保证执行顺序,所以这里选择的方法不会影响性能。如果使用forEachOrdered,我想它确实会有所作为。
      • @DidierL forEach 不需要保证执行顺序就可以发挥作用。不过,它可能只在并行流中这样做。
      • 我的意思是在并行上下文中:forEachOrdered 不能并行处理,因为它强制执行顺序。在这种情况下,单独的filter() 可能允许一些并行性。然而,通过一个简单的forEach,一切都可以并行化,所以不管你是否使用单独的filter()
      【解决方案3】:

      语法不同,但结果是一样的:)! forEach(..) 语法很清楚。过滤器语法被您的 lambda item -> item.contains("B") 隐藏。 如果没有 lambda,.filter 将采用“谓词”的实例:

      public Class MyPredicate<String> implements Predicate {
        @Override
        public boolean test(String myString) {
          return myString.contains("B");
        }
      }
      

      你会像这样使用它 - .filter(new MyPredicate())。

      【讨论】:

      • 你不应该这样写:至少写return myString.contains("B");而不是无用的if/else
      猜你喜欢
      • 2020-01-11
      • 1970-01-01
      • 2018-02-04
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      相关资源
      最近更新 更多