Haskell中的scanl在Java的streams中有什么相当之处?

7
作为这个问题是有关Python的,那么Java流中Haskell的scanl等价于什么?
到目前为止,我想到的最好方法是使用
reduce(identity, accumulator, combiner)

通过一个保持最新结果并在列表中累加结果的累加器,尽管组合器可能不会被使用。我也不确定如何防止它在并行情况下使用,因为那样它将无法工作。

也许Stream接口不适用于(相当于)scanl?


3
是的,“Stream”不是这里正确的接口。Java的Streams仅提供可以有效并行化的操作,其中不包括使用任意操作进行scanl。 - Louis Wasserman
1个回答

6

看起来标准的 Stream API 没有 scanl 的功能。其中一个原因是 scanl 是严格从左到右的操作,这使得很难从并行处理中获益(而并行处理是 Stream API 的重要组成部分)。不过,您可以使用像我免费的StreamEx库这样的第三方库。它扩展了标准的 Stream API 并添加了许多更有用的函数,包括 scanLeft

List<Integer> list = IntStreamEx.range(10).boxed().scanLeft(Integer::sum);
System.out.println(list);
// outputs [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

即使使用并行流,scanLeft 操作也可以保证正常工作,但是除非您有一些计算强度很高的上游操作可以并行化,否则您不太可能获得加速。


4
我知道原帖是询问流处理,但如果你正在使用数组,你也可以考虑使用Arrays.parallelPrefix函数;例如Arrays.parallelPrefix(arr, Integer::sum);。这不是一个严格的从左到右扫描,因为它需要一个初始值和一个二元运算符,但是嗯...... - Alexis C.
3
@AlexisC.,是的,这是一个不错的补充(考虑写下你的答案!)。然而需要注意的是,parallelPrefix 需要像 reduce 一样满足结合律。 - Tagir Valeev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接