代码之家  ›  专栏  ›  技术社区  ›  Melad Basilius

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

  •  9
  • Melad Basilius  · 技术社区  · 6 年前

    我正在阅读Java流的短路操作,在一些文章中发现 skip() 是短路操作。

    在另一篇文章中他们没有提到 跳过() 作为短路操作。

    现在我很困惑 跳过() 是否短路操作?

    2 回复  |  直到 6 年前
        1
  •  17
  •   Ousmane D.    6 年前

    From the java doc under the "Stream operations and pipelines" section :

    一个 中间操作短路,如果 无限输入,结果可能产生有限流 . 终点站 如果当输入无穷大时, 它可能在有限的时间内终止。

    强调我的。

    如果你打电话 skip 在无限输入下,它不会产生有限流,因此不会产生短路操作。

    唯一的短路中间操作 JDK8型 limit 因为它允许无限流上的计算在有限时间内完成。

    例子:

    如果要使用 跳过 :

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

    它不会产生 有限的 因此,您最终会得到一个类似“java.lang.OutOfMemoryError:java堆空间”的结果。

    而如果您要使用 限制 ,它将导致计算在 finite 时间:

    String[] limit = Stream.generate(() -> "test") // returns an infinite stream
                           .limit(20)
                           .toArray(String[]::new);
    
        2
  •  6
  •   Ousmane D.    6 年前

    只是想在这里加上我的两分钱,这个主意 一般来说 一条小溪的短路是无限复杂的(至少对我来说是这样,至少在某种意义上,我通常要挠两次头)。我会去的 skip 在答案的最后顺便说一句。

    举个例子:

    Stream.generate(() -> Integer.MAX_VALUE);
    

    这是一条无限的溪流,我们都同意这一点。让我们通过一个 记录在案 (不同于 跳过 ):

    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 -但它从来没有达到真正的短路任何东西。

    另一方面, 滤波器 短路操作,但您可以这样做(例如):

    someList.stream()
            .filter(x -> {
               if(x > 3) throw AssertionError("Just because");            
    })
    

    是的,很难看,但是短路了。。。我们就是这样(强调我们,因为 太多了 执行 short-circuiting reduce -引发没有堆栈跟踪的异常。

    java-9 另外还有一个短路的中间操作: takeWhile 有点像 limit 但在一定条件下。

    公平地说,大部分关于 跳过 是奥明已经给的,但最简单的回答是 没有这样的记录 . 一般来说(在某些情况下,文档是正确的),但这是您应该看到的第一个指示。见 限制 takeWhile公司 例如,它清楚地表明:

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