[英]Java Stream API lazy evaluation internals
我正在写一篇关于 Java Stream API 的文章。 我已经阅读了 Stream 的整个 package 文档,并且在这里查看了类似的问题。
如果我说以下内容:“stream 上的中间操作在终端操作被命中之前不会被评估,这实际上会执行它们,”我是否正确? 我在 StackOverflow 上看到了不同的答案,而且每个中间操作都返回一个 Stream,所以我想知道它是否只是返回自己,然后只是跟踪中间操作以执行它。 这就是“惰性评估/执行”的意思吗?
下面的javadoc老实说给了我混合的信号..也许我只是愚蠢
中间操作返回一个新的 stream。 他们总是很懒惰; 执行诸如 filter() 之类的中间操作实际上并没有执行任何过滤,而是创建了一个新的 stream,当被遍历时,它包含与给定谓词匹配的初始 stream 的元素。 直到管道的终端操作被执行,管道源的遍历才开始。
非常感谢您的时间; 抱歉,如果我遗漏了什么;(我已经坚持了很长时间!
PS: Stream和惰性求值非常相似,但是“每个中间操作都会创建一个新的stream,存储提供的操作/函数并返回新的stream。” 所以基本上,我的问题是,通过新的 stream,它是否意味着与给出的 stream 相同?
所以我想知道它是否刚刚返回
中间操作不会返回给定的 stream。 正如 JavaDoc 所说,它们返回一个新的 stream ,即一个新的 object。
如果是新的 object,它怎么知道之前在 stream 上所做的操作?
……你可能会问。
好吧,对象可以引用其他对象,对吗? 即使您返回执行“映射”的新Stream
,它仍然可以引用“旧流”(又名upstream )。 非常简化的例子:
class StreamThatDoesMapping<U, T> implements Stream<T> {
private Stream<U> upstream;
private Function<? super U, ? extends T> mappingFunction;
public StreamThatDoesMapping(Stream<U> upstream, Function<? super U, ? extends T> mappingFunction) {
this.upstream = upstream;
this.mappingFunction = mappingFunction;
}
// implementation details...
}
显然,在实现map
时,如果您将上游( this
)传递给StreamThatDoesMapping
,新的 stream 将“了解”您之前所做的操作! 这就是您可能实现map
的方式,再次非常简化:
public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
return new StreamThatDoesMapping<>(this, mapper);
}
当您进行终端操作时,您是在“最下游” Stream
object 上进行操作,即 object 将从其上游获取元素,因此上游将从其上游获取元素, 有点像链表,不是吗?
请注意,这只是下游了解上游的一种方式。 可能还有其他的,但这是ReferencePipeline
实现使用的。 这是 JDK 中大多数stream()
方法返回的内容。 我强烈建议查看他们的源代码。
如果我说以下内容:“stream 上的中间操作在终端操作被命中之前不会被评估,这实际上会执行它们,”我是否正确?
是的。
我想知道它是否只是自行返回,然后只是跟踪要执行的中间操作。
不。
它返回一个新的Stream
object,它是根据之前的Stream
ZA8CFDE633119446B8 定义的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.