在Stream的collect()终端操作中,如果供应商是像String这样的不可变对象会发生什么?

问题描述 投票:4回答:2

qazxsw poi方法的流是一种可变的减少。基于Java文档:

可变减少操作将输入元素累积到可变结果容器(例如Collection或StringBuilder)中,因为它处理流中的元素。

我尝试了以下内容,它编译没有问题。

collect()

如果供应商是StringBuffer,我查看collect操作,因为元素将附加到提供的StringBuffer。

由于String是一个不可变对象,因此可变减少如何在这里工作?它是否与reduce操作相同,每次实现累加器时都会创建一个新对象?

java java-stream collectors
2个回答
4
投票

由于String是一个不可变对象,因此可变减少如何在这里工作?

它没有。当你运行它时,你将得到一个空字符串(Stream<String> stream1 = Stream.of("w", "o", "l", "f"); String word = stream1.collect(String::new, String::concat, String::concat); System.out.println(word); 的结果)。如果Supplier返回一个不可变对象,编译器不能强制检查,这绝对是它无法做到的事情。由于您的容器是不可变的,因此只需忽略对它的更新。这就像做:

Supplier only

可能如果你把它写成一个lambda它会更有意义:

String s = "abc";
s.concat("def"); // the result is ignored here

另一方面,当你使用reduce时,你被迫返回一些东西:

Stream<String> stream1 = Stream.of("w", "o", "l", "f");
    String word = stream1.collect(
            String::new,
            (left, right) -> {
                left.concat(right); // result is ignored
            },
            String::concat);

当然,你仍然可以这样做:

String word = stream1.reduce(
            "",
            (x, y) -> {
                return x.concat(y);
            },
            (x, y) -> {
                return x.concat(y);
            });

如果你想打破它;但这不是重点。


1
投票

根据Oracle / Java文档:

搜集

String word = stream1.reduce(
            "",
            (x, y) -> {
                x.concat(y);
                return x; // kind of stupid, but you could
            },
            (x, y) -> {
                return x.concat(y);
            });

对此流的元素执行可变减少操作。可变减少是其中减少的值是可变结果容器(例如ArrayList),并且通过更新结果的状态而不是通过替换结果来合并元素。

<R> R collect(Supplier<R> supplier, <R,? super T> accumulator, <R,R> combiner)

可变减少

可变减少操作将输入元素累积到可变结果容器(例如Collection或StringBuilder)中,因为它处理流中的元素。如果我们想要获取字符串流并将它们连接成一个长字符串,我们可以通过普通减少来实现:

String concatenated = strings.reduce(“”,String :: concat)

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.function.Supplier-java.util.function.BiConsumer-java.util.function.BiConsumer-

因此,简而言之,它的工作原理是因为幕后java使用的是字符串构建器

© www.soinside.com 2019 - 2024. All rights reserved.