为什么新的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
行为?
答案 0 :(得分:11)
reduce
- 类数据并行操作用作数据集(例如元素数组)的一般值聚合操作。您可以使用它们来实现总和。
未指定数据集的值组合在一起(例如求和)的顺序,因此它们与Haskell中的foldl
或reduceLeft
/ 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
)。