Cumulative Sum using Java 8 stream API(使用 Java 8 流 API 的累积和)
问题描述
我有一个整数列表,比如 list1,我想获得另一个列表 list2,其中包含从开始到当前索引的累积总和.如何使用 Stream API java 8 做到这一点?
I have a List of Integer say list1, and I want to get another list list2 which will contain the cumulative sum up until the current index from start. How can I do this using Stream API java 8 ?
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));
}
如何将上述命令式代码更改为声明式?
How can I change above imperative style code into declarative one ?
list2 should be [1, 3, 6, 10]
推荐答案
Streams 不适合这种任务,因为涉及到状态(累积部分和).相反,您可以使用 Arrays.parallelPrefix
:
Streams are not suited for this kind of task, as there is state involved (the cumulative partial sum). Instead, you could use Arrays.parallelPrefix
:
Integer[] arr = list1.toArray(Integer[]::new);
Arrays.parallelPrefix(arr, Integer::sum);
List<Integer> list2 = Arrays.asList(arr);
这首先使用 list1 复制到一个数组中java/util/Collection.html#toArray(java.util.function.IntFunction)" rel="noreferrer">Collection.toArray
,从 JDK 11 开始可用.如果你是尚未在 Java 11 上,您可以将第一行替换为传统的 toArray
调用:
This first copies list1
to an array by using Collection.toArray
, which is available since JDK 11. If you are not on Java 11 yet, you could replace the first line with the traditional toArray
call:
Integer[] arr = list1.toArray(new Integer[0]);
此解决方案不使用流,但它是声明式,因为Arrays.parallelPrefix
接收累积运算作为参数(Integer::sum代码> 在这种情况下).
This solution doesn't use streams, yet it's declarative, because Arrays.parallelPrefix
receives the cumulative operation as an argument (Integer::sum
in this case).
时间复杂度为 O(N)
,但可能会涉及一些与设置并行处理所需的基础设施相关的非次要固定成本.但是,根据文档:
Time complexity is O(N)
, though there might be some non-minor constant costs involved associated with setting up the infrastructure needed for parallel processing. However, according to the docs:
并行前缀计算通常比大型数组的顺序循环更有效
Parallel prefix computation is usually more efficient than sequential loops for large arrays
所以看来这种方法值得一试.
So it seems it's worth giving this approach a try.
另外,值得一提的是,这种方法之所以有效,是因为 Integer::sum
是一个关联运算.这是一个要求.
Also, it's worth mentioning that this approach works because Integer::sum
is an associative operation. This is a requirement.
这篇关于使用 Java 8 流 API 的累积和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Java 8 流 API 的累积和


基础教程推荐
- Struts2 URL 无法访问 2022-01-01
- 问题http://apache.org/xml/features/xinclude测试日志4j 2 2022-01-01
- Spring AOP错误无法懒惰地为此建议构建thisJoinPoin 2022-09-13
- REST Web 服务返回 415 - 不支持的媒体类型 2022-01-01
- 修改 void 函数的输入参数,然后读取 2022-01-01
- 如何对 Java Hashmap 中的值求和 2022-01-01
- 存储 20 位数字的数据类型 2022-01-01
- 使用堆栈算法进行括号/括号匹配 2022-01-01
- 无法复制:“比较方法违反了它的一般约定!" 2022-01-01
- RabbitMQ:消息保持“未确认"; 2022-01-01