为了账号安全,请及时绑定邮箱和手机立即绑定

在Stream的collect()终端操作中,如果supplier是一个像String这样的不可变

在Stream的collect()终端操作中,如果supplier是一个像String这样的不可变

小怪兽爱吃肉 2021-09-15 15:31:51
collect()Stream 的方法是可变的归约。基于 Java 文档:可变归约操作在处理流中的元素时将输入元素累积到可变结果容器中,例如 Collection 或 StringBuilder。我尝试了以下方法,它编译没有问题。Stream<String> stream1 = Stream.of("w", "o", "l", "f");String word = stream1.collect(String::new, String::concat, String::concat);System.out.println(word);如果供应商是 StringBuffer,我会查看收集操作,因为元素将附加到提供的 StringBuffer。由于 String 是不可变对象,可变归约在这里如何工作?它是否与每次实现累加器时创建新对象的reduce操作相同?
查看完整描述

2 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

由于 String 是一个不可变对象,可变归约在这里如何工作?


它没有。当您运行它时,您将获得一个空字符串( 的结果Supplier only)。编译器不能强制检查供应商是否返回不可变对象,这绝对是它不能做的事情。由于你的容器是不可变的,对它的更新会被简单地忽略。这就像做:


String s = "abc";

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

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


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

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


String word = stream1.reduce(

            "",

            (x, y) -> {

                return x.concat(y);

            },

            (x, y) -> {

                return x.concat(y);

            });

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


String word = stream1.reduce(

            "",

            (x, y) -> {

                x.concat(y);

                return x; // kind of stupid, but you could

            },

            (x, y) -> {

                return x.concat(y);

            });

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


查看完整回答
反对 回复 2021-09-15
  • 2 回答
  • 0 关注
  • 257 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信