Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java流API惰性评估内部构件_Java_Java Stream - Fatal编程技术网

Java流API惰性评估内部构件

Java流API惰性评估内部构件,java,java-stream,Java,Java Stream,我正在写一篇关于Java流API的文章。我已经阅读了Stream的整个软件包文档,在这里我也浏览了类似的问题 如果我说: 流上的中间操作在终端操作被命中之前不会被评估,终端操作将实际执行它们, 我说的对吗?我在StackOverflow上看到了各种各样的答案,而且每个中间操作都返回一个流,所以我想知道它是否只返回自己,然后只跟踪要执行的中间操作。这就是所谓的懒惰评估/执行吗 下面的javadoc给了我混合的信号。。也许我只是愚蠢 中间操作返回一个新的流。他们总是懒惰; 执行诸如filter之类的

我正在写一篇关于Java流API的文章。我已经阅读了Stream的整个软件包文档,在这里我也浏览了类似的问题

如果我说: 流上的中间操作在终端操作被命中之前不会被评估,终端操作将实际执行它们, 我说的对吗?我在StackOverflow上看到了各种各样的答案,而且每个中间操作都返回一个流,所以我想知道它是否只返回自己,然后只跟踪要执行的中间操作。这就是所谓的懒惰评估/执行吗

下面的javadoc给了我混合的信号。。也许我只是愚蠢

中间操作返回一个新的流。他们总是懒惰; 执行诸如filter之类的中间操作实际上并不 执行任何筛选,但创建一个新流,当 遍历,包含与 给定谓词。管道源的遍历直到 执行管道的终端操作

非常感谢您抽出时间!对不起,如果我错过了什么;我已经在这上面呆了很长时间了

附言:非常相似,但是 每个中间操作创建一个新流,存储提供的操作/函数并返回新流。所以基本上,我的问题是,通过新的流,它是否意味着相同的流,它是给定的

如果我说的是:流上的中间操作在终端操作被命中之前不会被评估,而终端操作将实际执行它们,我是否正确

我想知道它是否只是返回了自己,然后在运行过程中跟踪要执行的中间操作

没有

它返回一个新的流对象,该对象是根据以前的流对象定义的

所以我想知道它是不是自己回来了

中间操作不会返回给定的流。正如JavaDoc所说,它们返回一个新流,即一个新对象

如果它是一个新对象,它如何知道以前在流上执行的操作

…你可能会问

对象可以引用其他对象,对吗?即使返回一个进行映射的新流,它仍然可以引用上游的旧流。非常简单的示例:

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...
}
当您执行终端操作时,您正在最下游的流对象上执行该操作,该对象将从其上游获取元素,而该上游将从其上游获取元素,依此类推。有点像链表,不是吗


请注意,这只是下游了解上游的一种方式。可能还有其他的,但这就是实现所使用的。这是JDK中大多数流方法返回的内容。我强烈建议您查看他们的源代码。

谢谢您的快速回答,但我并不真正理解您对上一个Stream对象的理解。假设Stream上唯一的方法是forEach和map。然后,您可以将Stream.mapf函数实现为返回新流{@Override public void forEachConsumer consumer{streamA.forEacha->consumer.acceptf.applya;}}。在调用forEach终端操作之前,它不会对streamA执行任何操作。新的流没有自己的数据。啊,是的,那么编译器如何记住在流上实际执行的操作呢?这就是让我生气的原因。非常感谢您的回答:d上面描述的匿名类I相当于类MappedStream{private final Stream streamA;private final Function f;@Override public void forEach…{…}。您可以为此类型填写构造函数。想象另一个类,实现类似,用于过滤器和所有其他操作。所以它可能会成为新的MappedStreamf、新的FilteredStreamfilter、…新的CollectionStreamcollection。。。
public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
    return new StreamThatDoesMapping<>(this, mapper);
}