Java8流中间操作是否生成新流?

Java8流中间操作是否生成新流?,java,java-stream,Java,Java Stream,当我在流上调用中间操作时,它们是否为每个中间操作创建新的流 List<Integer> list = List.of(1,2,3,4,5); list.stream().filter(i -> i > 4).map(o -> o*2).collect(Collectors.toList()); List List=List.of(1,2,3,4,5); list.stream().filter(i->i>4).map(o->o*2.collect(Collect

当我在流上调用中间操作时,它们是否为每个中间操作创建新的流

List<Integer> list = List.of(1,2,3,4,5);

list.stream().filter(i -> i > 4).map(o -> o*2).collect(Collectors.toList());
List List=List.of(1,2,3,4,5);
list.stream().filter(i->i>4).map(o->o*2.collect(Collectors.toList());

它创建了多少条流?1还是3

是的,对filter和map的调用都会创建一个新的无状态op,这是一个新的引用管道,它实现了接口。您正在创建3个新的无状态对象。

总之-是。对这种方法的每次调用都会创建另一个
对象。如果将链分解,并将这些中间操作分配给变量,则可以看到这一点:

Stream s1=list.Stream();
System.out.println(System.identityHashCode(s1));
流s2=s1。过滤器(i->i>2);
System.out.println(System.identityHashCode(s2));
流s3=s2.map(o->o*2);
System.out.println(System.identityHashCode(s3));
List result=s3.collect(Collectors.toList());
系统输出打印项次(结果);
样本输出:

1163157884
1747585824
1149319664
[6,8,10]


基本上,函数式编程的一个概念是
纯函数
,它具有确定性,并且没有称为
不变性的副作用。
api中的所有中间操作都是不可变的,并返回新的流

如文档中所述,所有中间操作(如
filter
map
等)都会返回新的流。例如
map
方法的文档如下:

Stream<R> map(Function<? super T,? extends R> mapper)

谢谢梅雷尼克。您还可以回答我的附带问题吗?如果多个线程试图将一个值插入到非同步列表中,那么结束列表是否会有差异?请注意,多个线程同时插入值,但是在读取时,它们都返回到main方法。当所有插入都完成时,列表将被阅读。@Faraz如果您有其他无关的问题,请将其作为问题发布,而不是作为评论发布。您是否可以回答此问题:@Faraz抱歉,我对Apache Spark没有任何经验(被答案和问题的混合所迷惑),无论是偶然还是故意,输入中过滤的元素数也是三个。所以,如果你能进一步澄清,如果你的问题是-“对于每个元素,都会有一个新的流?”或者你的问题是这样的“对于像
过滤器
映射
这样的每个操作,都会有一个新的流?谢谢Naman,我得到了答案。哦,好的@Naman。我知道你哪里糊涂了。我的问题清楚地说明了是否每个新的中间操作都创建并返回一个新的流。这是我的问题。答案也反映了这一点。我编辑了我的问题。现在,filter函数返回1个值。这个答案是最简洁的。但是,我不接受它,因为它缺乏深入的细节。如果您使用Intellij Idea,它可以提示您在每个操作中返回什么特定流。选中
镶嵌提示>方法链
选项。
public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) {
    Objects.requireNonNull(mapper);
    return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE,
                                 StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
        @Override
        Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) {
            return new Sink.ChainedReference<P_OUT, R>(sink) {
                @Override
                public void accept(P_OUT u) {
                    downstream.accept(mapper.apply(u));
                }
            };
        }
    };
}