当前位置: 首页 > 知识库问答 >
问题:

使用Java 8流API的累计和

胥诚
2023-03-14

我有一个整数列表,比如list1,我想获得另一个列表list2,它将包含从开始到当前索引的累计总和。我如何使用流API Java8来实现这一点?

List<Integer> list1 = new ArrayList<>();
list1.addAll(Arrays.asList(1, 2, 3, 4));
List<Integer> list2 = new ArrayList<>();
// initialization
list2.add(list1.get(0));
for(int i=1;i<list1.size();i++) {
// increment step
    list2.add(list2.get(i-1) + list1.get(i));
}

如何将上面的命令式代码更改为声明式代码?

list2 should be [1, 3, 6, 10]

共有1个答案

归翔
2023-03-14

流不适合这种任务,因为它涉及到状态(累积部分和)。相反,您可以使用arrays.parallelprefix:

Integer[] arr = list1.toArray(Integer[]::new);

Arrays.parallelPrefix(arr, Integer::sum);

List<Integer> list2 = Arrays.asList(arr);

首先使用collection.toArraylist1复制到一个数组中,自JDK11以来,它就可用了。如果您还没有使用Java11,可以用传统的toArray调用替换第一行:

Integer[] arr = list1.toArray(new Integer[0]);

此解决方案不使用流,但它是声明性的,因为arrays.parallelprefix将累积操作作为参数接收(本例中为integer::sum)。

时间复杂度是O(N),尽管可能存在一些与建立并行处理所需的基础结构相关的不小的恒定成本。然而,根据文件

对于大型数组,并行前缀计算通常比顺序循环更有效

因此,似乎值得尝试一下这种方法。

 类似资料:
  • 问题内容: 假设我有一个Java IntStream,是否可以将其转换为具有累积总和的IntStream?例如,以[4、2、6,…]开头的流应转换为[4、6、12,…]。 更笼统地说,应该如何实施有状态流操作?感觉这应该可行: 有一个明显的限制,即它仅适用于顺序流。但是,Stream.map明确需要无状态映射函数。我是否错过了Stream.statefulMap或Stream.cumulative

  • 问题内容: 我正在从大量客户端应用程序接收请求/事件。我想使用elasticsearch找出我的最高流量点。 我尝试过的一件事是使用嵌套的直方图进行过滤器聚合,然后使用嵌套的“术语”聚合通过脚本字段获取一天中不同的时间。以下是我的尝试,它的执行效果非常好(正如我期望的那样,因为我正在为每个文档执行脚本)。 我还考虑过将要查询的日期元素存储为文档的不同部分,例如: 这也闻起来像是对我的错误答案。 经

  • 我该怎么解决这个烂摊子? 提前致谢

  • 我试图实现列表中对象值的累积和。 对象如下所示: 我有一份清单 结果也应该是一个列表 如何使用Java流API实现它? 输入示例为: 所需输出为:

  • 我有一个rdd(String,Int),它是按键排序的 现在,我想用零开始第一个键的值,并将后续键作为前一个键的和。 例如:c1=0,c2=c1的值,c3=(c1值c2值),c4=(c1..c3值)预期输出: 有可能做到这一点吗?我用地图试过了,但总和没有保存在地图里。

  • 我有一个按月-年字符串属性排序的对象列表。我的对象类定义如下 我想对会员人数、非会员人数、会员付款、非会员付款进行累计和 所以我的新对象列表如下 我尝试与但它给我所有的总和不累积。 非常感谢任何指点。