如何解决使用Java流从整数列表计算累积和列表
我有以下列表:
INPUT :: 4 5 8 -11 9 5 -7 4 6 -6 -8 -11 80 -32 -56 -15 5 -49
OUTPUT :: 4 9 17 6 15 20 13 17 23 17 9 -2 78 46 -10 -25 -20 -69
我需要计算累计金额-列表含义
T(n) = T(n) + T(n-1) for n >0;
and
T(0) = T(0)
我想用Java流API进行计算,以便可以用Spark进行大数据计算。我在Java Streams中很幼稚,我尝试了几种表达式bt,但都不起作用 等效的结构化代码应类似于:
int[] numbers = {4,5,8,-11,9,-7,4,6,-6,-8,80,-32,-56,-15,-49};
int temp = 0;
for (int i = 0 ; i < numbers.length ; i++) {
temp = temp + numbers[i];
numbers[i] = temp;
}
解决方法
尝试一下。
int[] a = {4,5,8,-11,9,-7,4,6,-6,-8,80,-32,-56,-15,-49};
Arrays.parallelPrefix(a,(x,y) -> x + y);
System.out.println(Arrays.toString(a));
输出:
[4,17,15,20,13,23,-2,78,46,-10,-25,-20,-69]
,
有两种方法。
第一个效率很低,因为它基本上使用嵌套循环来累加值。第一个IntStream
指定值的范围,并且嵌套的IntStream创建一个可变范围,并将值从0到该范围的结尾求和。
int[] result1 = IntStream.range(0,vals.length).map(
i -> IntStream.rangeClosed(0,i).map(k->vals[k]).reduce(0,(a,b) -> a + b))
.toArray();
这更符合更常规的方法。流一个单一的0数组,然后使用它来累积值的连续和。
int[] result2 = Stream.of(new int[] { 0 })
.flatMapToInt(k -> IntStream.of(vals).map(v -> {
k[0] += v;
return k[0];
})).toArray();
System.out.println(Arrays.toString(result1));
System.out.println(Arrays.toString(result2));
两个都打印
[4,-69]
[4,-69]
但是您不能做得比这更好。
for (int i = 1; i < vals.length; i++) {
vals[i] += vals[i-1];
}
最重要的是坚持自己的财产。
,您可以尝试使用自定义收集器。
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1,2,3,5);
List<Integer> cumulatives = integers.stream().collect(CumulativeAdd.collector());
}
private static final class CumulativeAdd {
List<Integer> retArray= new ArrayList<>();
int sum = 0;
public void accept(Integer num) {
sum +=num;
retArray.add(sum);
}
public CumulativeAdd combine(CumulativeAdd other) {
throw new UnsupportedOperationException("Parallel Stream not supported");
}
public List<Integer> finish() {
return retArray;
}
public static Collector<Integer,?,List<Integer>> collector() {
return Collector.of(CumulativeAdd::new,CumulativeAdd::accept,CumulativeAdd::combine,CumulativeAdd::finish);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。