将子集的总和转换为可以并行执行的流

问题描述 投票:1回答:2

请考虑以下内容:

import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.DoubleStream;

public class Test {

    public static double sum(double[] x, int i, int L) {
        double s = 0;
        int hi = i + L;
        while (i < hi) {
            s += x[i - 1];
            i++;
        }
        return s;
    }

    /*public static double streamSum(double[] x, int i, int L) {
        return IntStream.range(0, x.length)
                        .parallel()
                        .filter(j -> (j < i + L))
                        .mapToObj(j -> x[j - 1])
                        .sum();
    }*/

    public static void main(String[] argv) {
        double[] x = {1, 2, 3, 4};
        System.out.println(sum(x, 1, 3));

    }

}

sum上面的数组为x,并且(基于1-indexing-不用问为什么,一定要那样做)获取起始索引i并获得长度为L的子集,对所述子集求和。上面的main中给出了一个示例。

如何解决上面的streamSum,以便除了使用并行流外,我获得与sum相同的输出?

java stream
2个回答
1
投票

[您说过您想对长度为i的子数组求和,您应该这样做。

    double r = IntStream.range(i, L+i)
                .parallel()
                .mapToDouble(id -> x[id-1])
                .sum();

     System.out.println(r);

减去1的原因是要考虑基于1的索引要求。


1
投票

这里是您问题中代码的修复。您应该注意this answer

double r = IntStream.range(i, j)
                .parallel()
                .mapToDouble(idx -> x[idx])
                .sum();

获得相同结果的更简单方法是:

Arrays.stream(x, i, j).parallel().sum();

Note:如果要通过length(L)而不是upper bound求和,只需在以上代码中将j替换为i + L。您编写的基于1的标准存在问题,因为Java数组默认为0。与它们一起使用,好像它们是基于1的,最终将导致IndexOutOfBoundException

© www.soinside.com 2019 - 2024. All rights reserved.