繁体   English   中英

Java 8 Streams 中间操作会产生新的流吗?

[英]Java 8 Streams intermediate operations produce new streams?

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

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

list.stream().filter(i -> i > 4).map(o -> o*2).collect(Collectors.toList());

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

基本上,函数式编程的概念之一是pure functions确定性且无副作用的pure functions ,称为immutability Stream api 中的所有中间操作都是不可变的,并返回新的 Stream。

正如Oracle文档中提到的,所有中间操作(如filtermap等)都返回新的流。 例如map方法的文档如下:

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

返回由将给定函数应用于此流的元素的结果组成的流。 这是一个中间操作。

类型参数: R - 新流的元素类型参数:

mapper - 应用于每个元素的无干扰、无状态函数

返回:新的流

有关更多信息,您可以查看 Java 中的 Stream 实现(例如返回新StatelessOp map方法)

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));
                }
            };
        }
    };
}

是的,对 filter 和 map 的调用都创建了一个新的StatelessOp ,它是一个实现Stream接口的新ReferencePipeline 您正在创建 3 个新的 StatelessOp 对象。

一句话—​​—是的。 每次调用此类方法都会创建另一个Stream对象。 如果您分解链并随着时间的推移将这些中间操作分配给变量,您就会看到这一点:

Stream<Integer> s1 = list.stream();
System.out.println(System.identityHashCode(s1));
Stream<Integer> s2 = s1.filter(i -> i > 2);
System.out.println(System.identityHashCode(s2));
Stream<Integer> s3 = s2.map(o -> o*2);
System.out.println(System.identityHashCode(s3));
List<Integer> result = s3.collect(Collectors.toList());
System.out.println(result);

示例输出:

1163157884
1747585824
1149319664
[6, 8, 10]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM