title: Understanding Java Stream reduce - parallel vs series
body: <p>I have Java code which uses lambdas and streams to find the average of a list of integers. It uses Stream.reduce(...) to find the sum of integers and then calculates average. The code works correctly even when I remove the parallel() call. Can someone explain why ? More questions after the code.</p>
  
  <pre><code>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&lt;Integer&gt; 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) -&gt; partialSum + (double) nextNumber,
                  //Add the sums of each mini stream.
                  (onePartialSum, anotherPartialSum) -&gt; (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);
  
      }
  }
  </code></pre>
  
  <p><strong>Output:</strong></p>
  
  <pre><code>Sum : expected value = 21.0, actual value = 21.0
  Average : expected value = 3.5, actual value = 3.5
  </code></pre>
  
  <p>Consider the code below for the function which is a <code>BinaryOperator&lt;U&gt; combiner</code> :</p>
  
  <pre><code>(onePartialSum, anotherPartialSum) -&gt; (onePartialSum + anotherPartialSum)
  </code></pre>
  
  <p>How does this line actually work in parallel and non-parallel ? My understanding is that in parallel, it takes the sum of each mini stream and adds it to the "total sum". Is that correct ? When stream is not parallel, then does it do zero + totalSum of single stream ? If yes, then a more accurate replacement for the previous line of code will be <code>(sum, onePartialSum) -&gt; (sum + onePartialSum)</code> where sum is already initialized to zero ???</p>