skip() 方法是短路操作吗?
Is the skip() method a short circuiting-operation?
我正在阅读有关 Java 流的短路操作,并在一些文章中发现 skip()
是一种短路操作。
在另一篇文章中他们没有提到 skip()
作为短路操作。
现在我很困惑; skip()
是不是短路操作?
From the java doc under the "Stream operations and pipelines" section :
An
intermediate operation is short-circuiting if, when presented with
infinite input, it may produce a finite stream as a result. A terminal
operation is short-circuiting if, when presented with infinite input,
it may terminate in finite time.
强调我的。
如果您要在无限输入上调用 skip
,它不会产生有限流,因此不是短路操作。
JDK8 中唯一的短路中间操作是 limit
,因为它允许在有限时间内完成无限流的计算。
示例:
如果您要使用 skip
执行此程序:
String[] skip = Stream.generate(() -> "test") // returns an infinite stream
.skip(20)
.toArray(String[]::new);
它不会产生 finite 流,因此你最终会得到类似于 "java.lang.OutOfMemoryError: Java heap space".
的东西
而如果您使用 limit
执行此程序,它将导致计算在 finite
时间内完成:
String[] limit = Stream.generate(() -> "test") // returns an infinite stream
.limit(20)
.toArray(String[]::new);
只是想在这里加上我的两分钱,这个想法一般来说 短路流是无限复杂的(至少对我来说,至少在某种意义上我通常不得不挠头两次)。顺便说一句,我会在答案的末尾到达 skip
。
我们以此为例:
Stream.generate(() -> Integer.MAX_VALUE);
这是一个无限的流,我们都同意这一点。让我们通过记录为这样的操作将其短路(不同于skip
):
Stream.generate(() -> Integer.MAX_VALUE).anyMatch(x -> true);
效果很好,添加一个 filter
:
怎么样?
Stream.generate(() -> Integer.MAX_VALUE)
.filter(x -> x < 100) // well sort of useless...
.anyMatch(x -> true);
这里会发生什么?好吧,这永远不会结束,即使有像 anyMatch
这样的短路操作——但它永远不会真正短路任何东西。
另一方面,filter
不是短路操作,但您可以这样设置(仅作为示例):
someList.stream()
.filter(x -> {
if(x > 3) throw AssertionError("Just because");
})
是的,它很丑,但它短路了...这就是我们(强调我们,因为 很多 的人,不同意)实施 short-circuiting reduce
-抛出没有堆栈跟踪的异常。
在 java-9
中添加了另一个短路的中间操作:takeWhile
其行为有点像 limit
但针对特定条件。
公平地说,关于 skip
的大部分答案已经由 Aomine 给出,但最简单的答案是 它没有记录在案.通常(在某些情况下会更正文档),但这是您应该查看的首要指示。请参阅 limit
和 takeWhile
示例,其中明确表示:
This is a short-circuiting stateful intermediate operation
我正在阅读有关 Java 流的短路操作,并在一些文章中发现 skip()
是一种短路操作。
在另一篇文章中他们没有提到 skip()
作为短路操作。
现在我很困惑; skip()
是不是短路操作?
From the java doc under the "Stream operations and pipelines" section :
An intermediate operation is short-circuiting if, when presented with infinite input, it may produce a finite stream as a result. A terminal operation is short-circuiting if, when presented with infinite input, it may terminate in finite time.
强调我的。
如果您要在无限输入上调用 skip
,它不会产生有限流,因此不是短路操作。
JDK8 中唯一的短路中间操作是 limit
,因为它允许在有限时间内完成无限流的计算。
示例:
如果您要使用 skip
执行此程序:
String[] skip = Stream.generate(() -> "test") // returns an infinite stream
.skip(20)
.toArray(String[]::new);
它不会产生 finite 流,因此你最终会得到类似于 "java.lang.OutOfMemoryError: Java heap space".
的东西而如果您使用 limit
执行此程序,它将导致计算在 finite
时间内完成:
String[] limit = Stream.generate(() -> "test") // returns an infinite stream
.limit(20)
.toArray(String[]::new);
只是想在这里加上我的两分钱,这个想法一般来说 短路流是无限复杂的(至少对我来说,至少在某种意义上我通常不得不挠头两次)。顺便说一句,我会在答案的末尾到达 skip
。
我们以此为例:
Stream.generate(() -> Integer.MAX_VALUE);
这是一个无限的流,我们都同意这一点。让我们通过记录为这样的操作将其短路(不同于skip
):
Stream.generate(() -> Integer.MAX_VALUE).anyMatch(x -> true);
效果很好,添加一个 filter
:
Stream.generate(() -> Integer.MAX_VALUE)
.filter(x -> x < 100) // well sort of useless...
.anyMatch(x -> true);
这里会发生什么?好吧,这永远不会结束,即使有像 anyMatch
这样的短路操作——但它永远不会真正短路任何东西。
另一方面,filter
不是短路操作,但您可以这样设置(仅作为示例):
someList.stream()
.filter(x -> {
if(x > 3) throw AssertionError("Just because");
})
是的,它很丑,但它短路了...这就是我们(强调我们,因为 很多 的人,不同意)实施 short-circuiting reduce
-抛出没有堆栈跟踪的异常。
在 java-9
中添加了另一个短路的中间操作:takeWhile
其行为有点像 limit
但针对特定条件。
公平地说,关于 skip
的大部分答案已经由 Aomine 给出,但最简单的答案是 它没有记录在案.通常(在某些情况下会更正文档),但这是您应该查看的首要指示。请参阅 limit
和 takeWhile
示例,其中明确表示:
This is a short-circuiting stateful intermediate operation