11

为什么新的JDK8Stream类只包含以下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)

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

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

?

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

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

4

1 回答 1

11

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

未指定数据集的值组合在一起(例如求和)的顺序,因此它们不对应于foldl在 Haskell 中找到或reduceLeft/foldLeft在 Scala 中找到。

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

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

组合器将只是一个总和:

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

例如,Scala Parallel Collections已经有一段时间了(搜索aggregate)。

于 2013-04-03T12:16:37.360 回答