为什么需要在管道中进行短路操作...在 Java 8 中

use*_*895 6 java-8 java-stream

我读了这个 api doc Stream api,它说(一个段落中的三个句子)

“如果中间操作在呈现无限输入时可能会产生有限流,则它是短路的。”

“如果终端操作在无限输入时可能在有限时间内终止,则它是短路的。”

“在管道中进行短路操作是无限流处理在有限时间内正常终止的必要条件,但不是充分条件。”

  1. 我不明白为什么中间和终端操作在出现无限输入时会短路。

  2. 我也不明白第三句话为什么短路是必要的,但处理无限流在有限时间内正常终止的条件不充分。

如果有人通过代码示例帮助我理解,那就太好了。

我对短路的了解就像

例如,if( a && b ) { ... }如果 a 为假,则不必检查 b。

Jea*_*nès 6

我不明白为什么中间和终端操作在出现无限输入时会短路。

因为它说“如果中间操作在呈现无限输入时可能会产生有限的流则它是短路的。”

示例:limit()如果它的输入是无限流,则输出是有限的,因此没有必要尝试消耗所有输入,因此它是短路的,因为即使输入无法在有限时间内处理,它也会在有限时间内产生输出有限的时间。

Stream<Integer> infiniteStream = Stream.iterate(0, i -> i + 1);
infiniteStream.limit(5).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

即使无限流是无限的,也会产生输出并在有限时间内终止。

我也不明白第三句话为什么短路是必要的,但处理无限流在有限时间内正常终止的条件不充分。

句子是:“在管道中进行短路操作是无限流处理在有限时间内正常终止的必要条件,但不是充分条件。”

示例:anyMatch是一个短路终端操作,但当输入流的元素验证谓词时才会在无限流上产生结果。

Stream<Integer> infiniteStream = Stream.iterate(0, i -> i);
infiniteStream.anyMatch(x->x==1).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

不会终止,但:

Stream<Integer> infiniteStream = Stream.iterate(0, i -> i);
infiniteStream.anyMatch(x->x==0).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

做。

逻辑表达式中的短路是另一种短路,但您可以考虑在表达式上会发生什么,例如if (f() && g())withf和/或g具有无限计算...问题:表达式何时可以有值?如果f()产生false那么即使g()是无限计算表达式也等于假。然后以某种方式,&&可以缩短一些无限计算。


Nam*_*man 2

在 和 文档已经建议的上下文中,Stream短路操作是等等limit(n)findFirst()

limit(n)诸如或 之类的短路操作findFirst()可以允许无限流上的计算在有限时间内完成。

例如

Stream stream;
stream.forEach(s -> {..do something}); // something is executed until all the elements of source are traversed
stream.limit(n).forEach(s -> {do something else}); // something else is executed just for 'n' times
Run Code Online (Sandbox Code Playgroud)