java - takeWhile, dropWhile 惰性 java9

标签 java scala functional-programming java-stream java-9

我认为在 scala 中这些方法工作正常但在 java9 dropWhile 中工作不同。

这里是 takeWhile 的例子

Stream.of("a", "b", "c", "de", "f", "g", "h")
                .peek(System.out::println)
                .takeWhile(s -> s.length() <= 1)
                .collect(Collectors.toList());

输出很好: a, b, c, de, [a, b, c] 它不处理“de”之后的元素,因此它按预期工作

但是 dropWhile 的工作方式与我预期的不同:

Stream.of("a", "b", "c", "de", "f", "g", "h")
                .peek(s -> System.out.print(s + ", "))
                .dropWhile(s -> s.length() <= 1)
                .collect(Collectors.toList());

输出是: a, b, c, de, f, g, h, [de, f, g, h]

所以它不会在“de”元素之后停止,它正在处理整个集合。

为什么要处理整个集合?我知道,它需要获取所有元素并将其收集到列表中,但它不应该在“de”元素之后停止处理吗?

最佳答案

看来,对于peek 的工作原理存在根本性的误解。它不与下一个后续链接操作相关联,如 dropWhile,而是与它背后的整个 Stream 管道相关联。并且不区分“处理元素”和“取所有元素”。

所以简单的代码

Stream.of("a", "b", "c", "de", "f", "g", "h")
      .peek(System.out::println)
      .collect(Collectors.toList());

“获取所有元素”,但在它们从流源传递到收集器时打印它们。

在你的例子中,无论一个元素是传递给dropWhile的谓词还是直接传递给Collector,都没有区别,无论哪种情况,都会被报告通过放在 both 之前的 peek 操作。

如果你使用

Stream.of("a", "b", "c", "de", "f", "g", "h")
      .dropWhile(s -> {
          System.out.println("dropWhile: "+s);
          return s.length() <= 1;
      })
      .peek(s -> System.out.println("collecting "+s))
      .collect(Collectors.toList());

相反,它会打印

dropWhile: a
dropWhile: b
dropWhile: c
dropWhile: de
collecting de
collecting f
collecting g
collecting h

展示了 dropWhile 的谓词的评估如何在第一个未接受的元素之后停止,而向 Collector 的传输从该元素开始。

这与 takeWhile 不同,其中 both,谓词求值和收集器停止消耗元素,因此没有剩余的消费者,整个 Stream 管道可以停止迭代来源。

关于java - takeWhile, dropWhile 惰性 java9,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41601498/

相关文章:

debugging - 如何在llvm源代码级调试信息中表示函数式语言调试信息?

java - 谷歌电子表格 Java API : URL from CellEntry?

java - onCompletion() 顺序在 Camel DSL 中是否重要?

scala - ENSIME 找不到正确的项目定义

haskell - 商类型如何帮助安全地暴露模块内部?

list - 在一个函数中修改多个列表并在Scala中返回

Java/SQL Server 2008 R2 Express 连接问题

java - 无法使用 C# 重写 PDFTextStripper.writeString(String text, List<TextPosition> textPositions) 方法?

scala - 如何将 ScalaMock 与 ScalaTest 结合使用?

Scala 向下还是 for 循环递减?