使用Java流从整数列表计算累积和列表
我有以下清单:使用Java流从整数列表计算累积和列表,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我有以下清单: 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流很幼
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流很幼稚,我已经尝试了几个表达式,但它们都不起作用
等效结构代码应如下所示:
int[] numbers = {4, 5, 8, -11, 9, 5, -7, 4, 6,-6, -8, -11, 80, -32, -56, -15, 5, -49};
int temp = 0;
for (int i = 0 ; i < numbers.length ; i++) {
temp = temp + numbers[i];
numbers[i] = temp;
}
int[]数字={4,5,8,-11,9,5,-7,4,6,-6,-8,-11,80,-32,-56,-15,5,-49};
内部温度=0;
for(int i=0;i
试试这个
int[] a = {4, 5, 8, -11, 9, 5, -7, 4, 6, -6, -8, -11, 80, -32, -56, -15, 5, -49};
Arrays.parallelPrefix(a, (x, y) -> x + y);
System.out.println(Arrays.toString(a));
输出:
[4, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
试试这个
int[] a = {4, 5, 8, -11, 9, 5, -7, 4, 6, -6, -8, -11, 80, -32, -56, -15, 5, -49};
Arrays.parallelPrefix(a, (x, y) -> x + y);
System.out.println(Arrays.toString(a));
输出:
[4, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -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, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
[4, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
但你做得再好不过了
for (int i = 1; i < vals.length; i++) {
vals[i] += vals[i-1];
}
for(int i=1;i
底线是坚持你所拥有的。这里有两种方法 第一种方法效率很低,因为它基本上使用嵌套循环来累积值。第一个
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, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
[4, 9, 17, 6, 15, 20, 13, 17, 23, 17, 9, -2, 78, 46, -10, -25, -20, -69]
但你做得再好不过了
for (int i = 1; i < vals.length; i++) {
vals[i] += vals[i-1];
}
for(int i=1;i
底线是坚持你所拥有的。你可以尝试使用自定义收集器
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 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);
}
}
publicstaticvoidmain(字符串[]args){
List integers=Arrays.asList(1,2,3,4,5);
List cumulatives=integers.stream().collect(cumulativead.collector());
}
私有静态最终类累积EADD{
List-retArray=new-ArrayList();
整数和=0;
公共void接受(整数num){
sum+=num;
重新排列。添加(总和);
}
公共累积EADD联合收割机(累积EADD其他){
抛出新的UnsupportedOperationException(“不支持并行流”);
}
公共列表完成(){
返回重新排列;
}
公共静态收集器(){
返回Collector.of(cumulativead::new,cumulativead::accept,cumulativead::combine,cumulativead::finish);
}
}
您可以尝试使用自定义收集器
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 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);
}
}
publicstaticvoidmain(字符串[]args){
List integers=Arrays.asList(1,2,3,4,5);
List cumulatives=integers.stream().collect(cumulativead.collector());
}
私有静态最终类累积EADD{
List-retArray=new-ArrayList();
整数和=0;
公共void接受(整数num){
sum+=num;
重新排列。添加(总和);
}
公共累积EADD联合收割机(累积EADD其他){
抛出新的UnsupportedOperationException(“不支持并行流”);
}
公共列表完成(){
返回重新排列;
}
公共静态收集器(){
返回Collector.of(cumulativead::new,cumulativead::accept,cumulativead::combine,cumulativead::finish);
}
}
Stream API在这里没有任何好处。spark和Lamanus之间有什么关系?@Lamanus我可以使用这个解决方案,并在中对JavaRDD进行一些dat atype更改Spark@Nikolas,我对流API完全陌生,你能帮我理解为什么流不能工作吗?如何以功能性的方式实现此逻辑?@NilKulkarni-Streams将起作用。但是没有额外的好处,事实上增加了额外的开销。流API在这里没有任何好处。spark与spark之间有什么关系?@Lamanus我可以使用这个解决方案,并在中对JavaRDD进行一些dat atype更改Spark@Nikolas,我对流API完全陌生,你能帮我理解为什么流不能工作吗?如何以功能性的方式实现此逻辑?@NilKulkarni-Streams将起作用。但这并没有额外的好处,事实上也增加了额外的开销。谢谢,但我没有足够的声誉。当然,这是一种优于streams的方法。但是OP确实指定了一个流解决方案。谢谢,但我不能进行升级投票,我没有足够的声誉。当然,与流相比,我更喜欢这种方法。但是OP确实指定了一个流解决方案。谢谢。这让我大开眼界,溪流可能不会每次都带来好处。谢谢。这让我大开眼界,溪流可能不会每次都带来好处。。