skip()方法是短路操作吗?

Mel*_*ius 9 java short-circuiting java-8 java-stream

我正在阅读有关Java流的短路操作,并在一些文章中发现这skip()是一个短路操作.

在另一篇文章中,他们没有提到skip()作为短路操作.

现在我很困惑; 是skip()短路还是不是?

Ous*_* D. 17

从"流操作和管道"部分下的java doc:

如果在呈现无限输入时,它可能产生有限流,则中间操作是短路的.如果在呈现无限输入时它可以在有限时间内终止,则终端操作是短路的.

强调我的.

如果你要调用skip无限输入,它将不会产生有限的流,因此不会产生短路操作.

JDK8中唯一的短路中间操作是limit允许无限流上的计算在有限时间内完成.

例:

如果您使用以下方法执行此程序skip:

String[] skip = Stream.generate(() -> "test") // returns an infinite stream
                      .skip(20) 
                      .toArray(String[]::new);
Run Code Online (Sandbox Code Playgroud)

它不会产生有限的流,因此你最终会得到"java.lang.OutOfMemoryError:Java堆空间"的内容.

而如果你要使用limit它来执行这个程序,它将导致计算在一段finite时间内完成:

String[] limit = Stream.generate(() -> "test") // returns an infinite stream
                       .limit(20)
                       .toArray(String[]::new);
Run Code Online (Sandbox Code Playgroud)


Eug*_*ene 6

只是想在这里加上我的两分钱,这个想法一般来说是一个短路的流是无限复杂的(至少对我而言,至少在某种意义上我必须经常擦头两次).我会skip在答案的最后得到btw.

我们以此为例:

Stream.generate(() -> Integer.MAX_VALUE);
Run Code Online (Sandbox Code Playgroud)

这是一个无限的流,我们都同意这一点.让我们通过记录为这样的操作使其短路(不像skip):

Stream.generate(() -> Integer.MAX_VALUE).anyMatch(x -> true);
Run Code Online (Sandbox Code Playgroud)

这很好用,添加一个filter:

Stream.generate(() -> Integer.MAX_VALUE)
      .filter(x -> x < 100) // well sort of useless...
      .anyMatch(x -> true);
Run Code Online (Sandbox Code Playgroud)

这会发生什么?好吧,即使有像这样的短路操作,这也永远不会完成anyMatch- 但实际上并没有实现任何短路.

在另一方面,filter不是一个短路操作,但你可以把它作为这样的(只是为例):

someList.stream()
        .filter(x -> {
           if(x > 3) throw AssertionError("Just because");            
})
Run Code Online (Sandbox Code Playgroud)

是的,它很难看,但它是短路的...这就是我们(强调我们,因为很多人,不同意)实现short-circuiting reduce- 抛出一个没有堆栈跟踪的异常.

在另外java-9还有一个短路的中间操作:takeWhile这种操作类似于limit某种情况.

公平地说,答案的主要部分skip是Aomine已经给出的答案,但最简单的答案是它没有记录在案.一般而言(有些情况下会更正文档),但这是您应该注意的第一个指示.见limittakeWhile例如,明确表示:

这是一种短路状态中间操作