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 的累积和
基础教程推荐
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01