流和延迟计算

2022-08-31 17:13:50

我正在阅读java 8 API关于流抽象的内容,但我不太理解这句话:

中间操作返回新流。他们总是懒惰;执行中间操作(如 filter())实际上并不执行任何筛选,而是创建一个新流,该流在遍历时包含与给定谓词匹配的初始流的元素。在执行管道的终端操作之前,不会开始遍历管道源。

当筛选器操作创建新流时,该流是否包含已筛选的元素?它似乎理解流仅在遍历时(即使用终端操作)才包含元素。但是,那么,过滤后的流包含什么呢?我很困惑!!!


答案 1

这意味着过滤器仅在终端操作期间应用。可以这样想:

public Stream filter(Predicate p) {
    this.filter = p; // just store it, don't apply it yet
    return this; // in reality: return a new stream
}
public List collect() {
    for (Object o : stream) {
        if (filter.test(o)) list.add(o);
    }
    return list;
}

(这不会编译,是对现实的简化,但原则是存在的)


答案 2

流是惰性的,因为除非调用终端操作,否则不会计算中间操作。

每个中间操作都会创建一个新流,存储提供的操作/函数并返回新流。

管道会累积这些新创建的流。

调用终端操作时,开始遍历流,并逐个执行关联的功能。

并行流不会“逐个”评估流(在终端点)。这些操作是同时执行的,具体取决于可用的内核。


推荐