在什么情况下,Java 8 streams中调用了'reduce‘的第三个参数?
下面的代码尝试遍历字符串列表,并将每个字符串的第一个字符的代码点值相加。最后一个lambda返回的值似乎从未被使用过,如果您插入一个println,它似乎从未被调用过。文档描述它是一个‘组合器’,但我找不到更多细节……
int result =
data.stream().reduce(0, (total,s) -> total + s.codePointAt(0), (a,b) -> 1000000); 发布于 2014-04-02 22:10:22
你是在说this function吗?
reduce U reduce(U单位,BiFunction累加器、BinaryOperator组合器)
使用提供的标识、累积和组合函数对此流的元素执行缩减。这相当于:
U result = identity;for (T element : this stream) result = accumulator.apply(result,element)返回结果;但不限于按顺序执行。标识值必须是组合器函数的标识。这意味着对于所有u,组合器(identity,u)等于u。此外,组合器函数必须与累加器函数兼容;对于所有u和t,必须满足以下条件:
combiner.apply(u,accumulator.apply(identity,t)) == accumulator.apply(u,t)这是一个终端操作。
API注意:使用这种形式的许多缩减可以更简单地由map和reduce操作的显式组合来表示。累加器函数充当融合的映射器和累加器,这有时可能比单独的映射和缩减更有效,例如,当知道以前减少的值可以避免一些计算时。类型参数:u-结果参数的类型: identity -合并器函数的标识值累加器-用于将附加元素合并到结果合并器中的关联、非干扰、无状态函数-用于组合两个值的关联、非干扰、无状态函数,必须与累加器函数兼容返回:缩减的结果另请参阅: reduce( BinaryOperator),reduce(Object,BinaryOperator)
我假设它的目的是允许并行计算,所以我猜测只有在并行执行缩减时才使用它。如果它是按顺序执行的,则不需要使用combiner。我不能确定这一点--我只是根据文档注释"...不被限制为按顺序执行“以及注释中提到的许多其他”并行执行“来猜测。
发布于 2014-09-24 17:29:09
我认为java.util.stream包摘要中的Reduction operations段落可以回答这个问题。让我在这里引用最重要的部分:
在其更一般的形式中,对产生<U>类型结果的<T>类型的元素执行reduce操作需要三个参数:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);在这里,identity元素既是约简的初始种子值,也是没有输入元素时的默认结果。累加器函数获取部分结果和下一个元素,并生成新的部分结果。组合器函数组合两个部分结果以产生新的部分结果。(在并行缩减中,合并器是必需的,其中输入被分区,为每个分区计算部分累加,然后合并部分结果以产生最终结果。)更正式地说,标识值必须是组合器函数的标识。这意味着对于所有u,combiner.apply(identity, u)等于u。此外,组合器函数必须是关联的,并且必须与累加器函数兼容:对于所有u和t,combiner.apply(u, accumulator.apply(identity, t))必须是equals() to accumulator.apply(u, t)。
三参数形式是两参数形式的推广,将映射步骤合并到累加步骤中。我们可以使用更一般的形式重新转换简单的权重总和示例,如下所示:
int sumOfWeights = widgets.stream()
.reduce(0,
(sum, b) -> sum + b.getWeight())
Integer::sum);不过,显式的map-reduce形式更具可读性,因此通常应该首选。对于通过将映射和归约组合到单个函数中可以优化大量工作的情况,提供了广义形式。
换句话说,据我所知,三参数形式在两种情况下是有用的:
当并行执行matters.
前面在同一文档中提到了显式形式:
int sumOfWeights = widgets.parallelStream()
.filter(b -> b.getColor() == RED)
.mapToInt(b -> b.getWeight())
.sum();发布于 2014-04-26 19:07:14
确认combiner用法的简单测试代码:
String[] strArray = {"abc", "mno", "xyz"};
List<String> strList = Arrays.asList(strArray);
System.out.println("stream test");
int streamResult = strList.stream().reduce(
0,
(total,s) -> { System.out.println("accumulator: total[" + total + "] s[" + s + "] s.codePointAt(0)[" + s.codePointAt(0) + "]"); return total + s.codePointAt(0); },
(a,b) -> { System.out.println("combiner: a[" + a + "] b[" + b + "]"); return 1000000;}
);
System.out.println("streamResult: " + streamResult);
System.out.println("parallelStream test");
int parallelStreamResult = strList.parallelStream().reduce(
0,
(total,s) -> { System.out.println("accumulator: total[" + total + "] s[" + s + "] s.codePointAt(0)[" + s.codePointAt(0) + "]"); return total + s.codePointAt(0); },
(a,b) -> { System.out.println("combiner: a[" + a + "] b[" + b + "]"); return 1000000;}
);
System.out.println("parallelStreamResult: " + parallelStreamResult);
System.out.println("parallelStream test2");
int parallelStreamResult2 = strList.parallelStream().reduce(
0,
(total,s) -> { System.out.println("accumulator: total[" + total + "] s[" + s + "] s.codePointAt(0)[" + s.codePointAt(0) + "]"); return total + s.codePointAt(0); },
(a,b) -> { System.out.println("combiner: a[" + a + "] b[" + b + "] a+b[" + (a+b) + "]"); return a+b;}
);
System.out.println("parallelStreamResult2: " + parallelStreamResult2);输出:
stream test
accumulator: total[0] s[abc] s.codePointAt(0)[97]
accumulator: total[97] s[mno] s.codePointAt(0)[109]
accumulator: total[206] s[xyz] s.codePointAt(0)[120]
streamResult: 326
parallelStream test
accumulator: total[0] s[mno] s.codePointAt(0)[109]
accumulator: total[0] s[abc] s.codePointAt(0)[97]
accumulator: total[0] s[xyz] s.codePointAt(0)[120]
combiner: a[109] b[120]
combiner: a[97] b[1000000]
parallelStreamResult: 1000000
parallelStream test2
accumulator: total[0] s[mno] s.codePointAt(0)[109]
accumulator: total[0] s[xyz] s.codePointAt(0)[120]
accumulator: total[0] s[abc] s.codePointAt(0)[97]
combiner: a[109] b[120] a+b[229]
combiner: a[97] b[229] a+b[326]
parallelStreamResult2: 326https://stackoverflow.com/questions/22808485
复制相似问题