首页 > 解决方案 > 组合器永远不会在归约操作中被调用(但是强制性的)

问题描述

我试图弄清楚累加器和组合器在reduce流操作中的作用。

    List<User> users = Arrays.asList(new User("John", 30), new User("Julie", 35));

    int result = users.stream()
            .reduce(0,
                    (partialAgeResult, user) -> {
                        // accumulator is called twice
                        System.out.println(MessageFormat.format("partialAgeResult {0}, user {1}", partialAgeResult, user));
                        return partialAgeResult + user.getAge();
                    },
                    (integer, integer2) -> {
                        // combiner is never called
                        System.out.println(MessageFormat.format("integer {0}, integer2 {1}", integer, integer2));
                        return integer * integer2;
                    });

    System.out.println(MessageFormat.format("Result is {0}", result)); 

我注意到组合器从未执行过,结果为 65。如果我使用users.parallelStream()组合器,则执行一次,结果为 1050。

为什么streamparallelStream产生不同的结果?我没有看到并行执行此操作的任何副作用。

简单流版本中组合器的目的是什么?

标签: java-streamjava-11

解决方案


问题就在这里。您是在组合器中相乘而不是相加。

 (integer, integer2) -> {
                        // combiner is never called
                        System.out.println(MessageFormat.format("integer {0}, integer2 {1}", integer, integer2));
                        return integer * integer2; //<----- Should be addition
                    });

组合器用于适当地组合并行操作的各个部分,因为这些操作可以在原始流的各个“片段”上独立执行。

一个简单的例子是对元素列表求和。您可以在并行操作中获得各种部分和,因此您需要在组合器中对部分和求和以获得总和(您可以自己尝试查看的一个很好的练习)。


推荐阅读