Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解Java Stream reduce-并行与串行_Java_Lambda - Fatal编程技术网

了解Java Stream reduce-并行与串行

了解Java Stream reduce-并行与串行,java,lambda,Java,Lambda,我有Java代码,它使用lambda和streams来查找整数列表的平均值。它使用Stream.reduce(…)查找整数之和,然后计算平均值。即使删除parallel()调用,代码也能正常工作。有人能解释一下原因吗?代码后面还有更多问题 import java.util.Arrays; import java.util.List; public class Temp { public static void main(String [] args){ //For ex

我有Java代码,它使用lambda和streams来查找整数列表的平均值。它使用Stream.reduce(…)查找整数之和,然后计算平均值。即使删除parallel()调用,代码也能正常工作。有人能解释一下原因吗?代码后面还有更多问题

import java.util.Arrays;
import java.util.List;

public class Temp {
    public static void main(String [] args){
        //For example, consider a list of a *series* of numbers in increasing order.
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        int n = numbers.get(numbers.size()-1);//n = 6 is the number of numbers in list.

        double expectedSum = (n * (n + 1))/2;//By mathematical formula for increasing series.

        Double sum = numbers
                //Take a stream of integers.
                .stream()
                //Split the stream into mini streams and calculate sum of each of mini stream.
                .parallel()
                //Reduce all the numbers in a stream to their sum.
                .reduce(
                        //start with a partial sum of 0.
                0.0,
                //For a stream, calculate the sum of all the numbers.
                (partialSum, nextNumber) -> partialSum + (double) nextNumber,
                //Add the sums of each mini stream.
                (onePartialSum, anotherPartialSum) -> (onePartialSum + anotherPartialSum)
        );

        System.out.println("Sum : expected value = " + expectedSum + ", actual value = " + sum);

        double expectedAverage = expectedSum/numbers.size();
        double average = sum/numbers.size();

        System.out.println("Average : expected value = " + expectedAverage + ", actual value = " + average);

    }
}
考虑下面的代码,该函数是一个
二进制运算符组合器

(onePartialSum, anotherPartialSum) -> (onePartialSum + anotherPartialSum)

这条线实际上是如何并行和非并行工作的?我的理解是,在并行过程中,它取每个迷你流的总和,并将其添加到“总和”中。对吗?当流不平行时,它会做零+单个流的总和吗?如果是,则前一行代码的更准确替换将是
(sum,onePartialSum)->(sum+onePartialSum)
,其中sum已被初始化为零??

并行:

Sum : expected value = 21.0, actual value = 21.0
Average : expected value = 3.5, actual value = 3.5
System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().parallel()
    .reduce(/*identity*/1, /*accumulator*/(s, s2) -> s + s2, /*combiner*/(s, s2) -> s + s2));
System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream()
    .reduce(/*identity*/1, /*accumulator*/(s, s2) -> s + s2, /*combiner*/(s, s2) -> s + s2));
产出:20

累加器的参数是标识和每个流值

工作:

1+1, 1+2, 1+3, 1+4, 1+5 // Output of accumulator is 2,3,4,5,6
2+3 in one thread, 4+5 in another thread and then 5/*(2+3)*/+9/*(4+5)*/ and then 14/*(5+9)*/+6 = 20
1(identity) + 1(first element) = 2(new identity)
2(new identity) + 2(second element) = 4(new identity)
4(new identity) + 3(third element) = 7(new identity)
7(new identity) + 4(third element) = 11(new identity)
11(new identity) + 5(third element) = 16(new identity)
组合器的参数是累加器的输出

工作:

1+1, 1+2, 1+3, 1+4, 1+5 // Output of accumulator is 2,3,4,5,6
2+3 in one thread, 4+5 in another thread and then 5/*(2+3)*/+9/*(4+5)*/ and then 14/*(5+9)*/+6 = 20
1(identity) + 1(first element) = 2(new identity)
2(new identity) + 2(second element) = 4(new identity)
4(new identity) + 3(third element) = 7(new identity)
7(new identity) + 4(third element) = 11(new identity)
11(new identity) + 5(third element) = 16(new identity)
串联:

Sum : expected value = 21.0, actual value = 21.0
Average : expected value = 3.5, actual value = 3.5
System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream().parallel()
    .reduce(/*identity*/1, /*accumulator*/(s, s2) -> s + s2, /*combiner*/(s, s2) -> s + s2));
System.out.println(Arrays.asList(1, 2, 3, 4, 5).stream()
    .reduce(/*identity*/1, /*accumulator*/(s, s2) -> s + s2, /*combiner*/(s, s2) -> s + s2));
产出:16

在串联模式下,不会执行组合器,累加器的参数为identity和每个流值,但每个流的结果设置为identity

工作:

1+1, 1+2, 1+3, 1+4, 1+5 // Output of accumulator is 2,3,4,5,6
2+3 in one thread, 4+5 in another thread and then 5/*(2+3)*/+9/*(4+5)*/ and then 14/*(5+9)*/+6 = 20
1(identity) + 1(first element) = 2(new identity)
2(new identity) + 2(second element) = 4(new identity)
4(new identity) + 3(third element) = 7(new identity)
7(new identity) + 4(third element) = 11(new identity)
11(new identity) + 5(third element) = 16(new identity)

我希望您能理解。

“即使我删除了parallel()调用,代码也能正常工作”——为什么它不能正常工作?您的累加器和合并器都正确实现,这意味着流将按照设计并行或顺序工作。@Slaw-我想了解合并器是如何并行或串行工作的。这就是我的最后一个问题asksIIRC,对于顺序流不会调用合并器,因为从来没有两组数据可以从多个线程合并。当并行时,流可以拆分源
拆分器
并使用多个线程;在这种情况下,每个线程都有自己的一组数据,需要在最后进行组合,因此需要组合器。