Stream.findAny是短路操作吗? [英] Is Stream.findAny a short-circuit operation?

查看:406
本文介绍了Stream.findAny是短路操作吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这段代码

Object found = collection.stream()
    .filter( s -> myPredicate1(s))
    .filter( s -> myPredicate2(s))
    .findAny()

它会处理整个流,并为所有元素调用 myPredicate1 myPredicate2 采集?或者,实际找到该值需要调用多少个谓词?

Will it process entire stream, and call both myPredicate1 and myPredicate2 for all elements of the collection? Or will as many predicates be called as are needed to actually find the value?

推荐答案

是的,因为 Stream.findAny () 文档说明:

Yes it is, as the Stream.findAny() documentation states:


这是一个短路终端操作。

This is a short-circuiting terminal operation.

这是一种常见的误解,即流中的对象被推到消费操作。它实际上是另一种方式 - 消耗操作拉动每个元素。

It's a common misconception that objects in stream are "pushed" towards consuming operation. It's actually the other way around - the consuming operation pulls each element.

对于顺序流,只有在查找匹配值时才会调用许多谓词。
并行流可以执行更多谓词,但也会在找到元素后立即停止执行。

For sequential streams only as many predicates will be called as are needed to find matching value. Parallel streams may execute more predicates, but will also stop execution as soon as an element is found.

public class StreamFilterLazyTest {

  static int stI = 0;

  static class T { 

    public T() {
      super();
      this.i = ++stI;
    }

    int i;

    int getI() {
      System.err.println("getI: "+i);
      return i;
    }
  }

  public static void main(String[] args) {
    T[] arr = {new T(), new T(), new T(), new T(), new T(), new T(), new T(), new T(), new T(), new T()};
    Optional<T> found = Arrays.stream(arr).filter(t -> t.getI() == 3).findAny();
    System.out.println("Found: "+found.get().getI());
  }
}

将打印:

getI: 1
getI: 2
getI: 3
Found: 3

这篇关于Stream.findAny是短路操作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆