JDK8批量收集操作库中的奇怪“reduce”方法组

时间:2013-04-03 12:12:59

标签: java collections lambda java-8

为什么新的JDK8 Stream类仅包含以下reduce方法:

T reduce(BinaryOperator<T> reducer)
T reduce(T identity, BinaryOperator<T> reducer)
U reduce(U identity, BiFunction<U, ? super T, U> reducer, 
    BinaryOperator<U> combiner)

但不是一种与其他语言(例如Haskell reduce)中找到的fold / foldl :: (a -> b -> a) -> a -> [b] -> a函数相对应的明显方法,它们看起来像这样:

U reduce(U identity, BiFunction<U, ? super T, U> reducer)

相反,有一个类似的方法,它有一个额外的combiner参数。我甚至不确定如何使用它,因为我链接到上面的API文档在示例中没有使用此参数,它只提到了它所需的属性。

为什么JDK8方法是这样做的,我如何用它们模拟标准fold行为?

1 个答案:

答案 0 :(得分:11)

reduce - 类数据并行操作用作数据集(例如元素数组)的一般值聚合操作。您可以使用它们来实现总和。

未指定数据集的值组合在一起(例如求和)的顺序,因此它们与Haskell中的foldlreduceLeft / foldLeft不对应在斯卡拉发现。

当聚合的结果类型与元素的类型不同时,将使用第三行中的额外combiner参数。在这些情况下,您必须指定如何将两个结果组合在一起。 假设您想使用第三个reduce实现字符串中元音的计数。数据元素是字符,reducer指定字符和当前计数的组合方式:

(Integer count, Character c) -> if (isVowel(c)) count + 1 else count

组合器只是一个总和:

(Integer count1, Integer count2) -> count1 + count2
例如,

Scala Parallel Collections包含这些for a while now(搜索aggregate)。