Преобразование суммы подмножества в поток, который может выполняться параллельно - PullRequest
2 голосов
/ 31 марта 2020

Примите во внимание следующее:

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-индексации - не спрашивайте почему, так и должно быть) берет старт индекс i и получает подмножество длины L, суммируя указанное подмножество. Пример приведен в main выше.

Как исправить streamSum выше, чтобы получить тот же вывод, что и sum, за исключением использования параллельного потока?

Ответы [ 2 ]

2 голосов
/ 31 марта 2020

Вы сказали, что хотите суммировать подмассив, начинающийся с i, для длины L. Вы должны сделать это следующим образом.

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

System.out.println(r);

Причина вычитания 1 заключается в учете требования индекса на основе 1.

1 голос
/ 31 марта 2020

Вот исправление для кода в вашем вопросе. Вы должны принять к сведению этот ответ .

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

Еще более простой способ добиться того же результата:

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

Примечание : если вы хотите суммировать длина (L) , а не верхняя граница , просто замените j на i + L в приведенном выше коде. Ваш критерий того, что он должен быть основан на 1, является проблемным c, как написано, так как Java массивы по умолчанию основаны на 0; работа с ними, как будто они основаны на 1, в конечном итоге вызовет IndexOutOfBoundException.

...