当前位置: 首页 > 面试题库 >

Stream.collect方法中的合并器如何在Java 8中工作?

裴俊豪
2023-03-14
问题内容

我创建了一个简单的演示:

public static void main(String[] args) {
        List<String> list2 = Arrays.asList("adf", "bcd", "abc", "hgr", "jyt", "edr", "biu");

String collect = list2.stream().collect(String::new, (res, elem) -> {
              res=res.concat(" ").concat(elem);
//            System.out.printf("res=%s, elem=%s\n", res.isEmpty(), elem);

        }, (res1, res2) -> {
            System.out.printf("res1=%s, res2=%s\n", res1, res2);            
        });
        System.out.println("collect=" + collect);
}

问题在于的BiConsumer combiner一部分collect根本没有运行。

如果我只使用parallelStream()两个参数res1并且res2等于provider ,它将运行String::new

如何使方法combiner工作collect


问题答案:

首先,由于没有要合并的内容,因此不需要在非并行流中执行合并器。

其次,您的问题源于使用String::newString.concat。应该使用累加器通过将第二个参数与第一个参数结合来修改第一个参数,但是由于Java中的字符串是不可变的,因此您的代码不会产生任何结果。

          res=res.concat(" ").concat(elem);

将创建一个新字符串,然后将其丢弃。您想改用StringBuilder,以便保留中间结果:

public static void main(String[] args) {
    List<String> list2 = Arrays.asList("adf", "bcd", "abc", "hgr", "jyt", "edr", "biu");

    String collect = list2.stream().collect(StringBuilder::new, (res, elem) -> {
        res.append(" ").append(elem);
    }, (res1, res2) -> {
        res1.append(res2.toString());
        System.out.printf("res1=%s, res2=%s\n", res1, res2);
    }).toString();
    System.out.println("collect=" + collect);
}

这也可以与并行流一起正常工作

res1 = hgr jyt,res2 = jyt
res1 = bcd abc,res2 = abc
res1 = adf bcd abc,res2 = bcd abc
res1 = edr biu,res2 = biu
res1 = hgr jyt edr biu,res2 = edr biu
res1 = adf bcd abc hgr jyt edr biu,res2 = hgr jyt edr biu
collect = adf bcd abc hgr jyt edr biu




 类似资料:
  • 如果我使用,但和两个参数等于supplier,它就会运行。 如何使在方法中工作?

  • 我正在为Java8证书做准备,下面的内容让我有点困惑,也许有人能帮我?在这个例子中,一个Squirrel类被建模。它有一个名称和一个权重。现在你可以创建一个比较器类来使用这两个字段对它进行排序。所以首先按名称排序,然后按权重排序。类似于这样: 到现在为止,一直都还不错。。但接下来是令人困惑的部分。在代码示例下面,它们声明您可以使用方法链接在一行中编写此代码。也许我误解了,但当我将比较部分和then

  • 我对方法引用在Java8中是如何工作的有些困惑。我编写了下面的代码段用于过滤文件夹中的隐藏文件。他们正在产生正确的结果。我不理解->listFiles方法的方法签名是如何在这个代码段的选项2中工作的。 这是我在Java8文档中发现的

  • 如果我从集合界面有两个对象列表 列表1={约翰,蒂姆,汤姆} 列表2={约翰,蒂姆} 这两个列表都是ArrayList的实例 Java怎么知道list2是否包含在list1中,list1.containsall(list2)? 我知道Java使用包含方法内部实现的容器()方法,和包含方法使用相等()方法。我理解差异,但我不确定Java如何遍历列表1的元素。 如果我使用列表1。containsAll

  • 问题内容: 我有一个带有4列的(example-)数据框: 我现在想将B,C和D列合并/合并到新的E列,如本例所示: 我在这里发现了一个非常类似的问题,但这在A列的末尾添加了合并的列B,C和D: 感谢帮助。 问题答案: 选项1 使用和 选项2 使用分配和 选项3 最近,我喜欢第3个选项。 使用

  • 我想转换哈希映射 代码如下。但是当初始Hashmap中存在相同长度的键时,它会触发抛出Exception的合并函数(我打算这样做,因为在我的情况下不会有相同的字符串)。我想知道为什么会触发合并函数,因为toMap()的JavaDoc说“如果映射的键包含重复项(根据Object#equals(Object)),则将值映射函数应用于每个相等的元素,并使用提供的合并函数合并结果。”我认为在我的代码中,“