Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Computing sum and sum-of-squares at the same time with Streams

I was wondering if there is any way to achieve the following within a single iteration over the array. Simply to have two different results out of stream.

double sum = Arrays.stream(doubles).sum();
double sumOfSquares = Arrays.stream(doubles).map(d -> d * d).sum();
like image 659
HectorBarbossa Avatar asked May 20 '16 16:05

HectorBarbossa


People also ask

How do you do multiple operations on a stream?

The correct approach would be to use . map() which, like the name says, maps one value to another. In your case the first operation you want to do is to map a Person to a JSONObject. The second operation is a reducer function where you want to reduce all JSONObjects to one JSONArray object.

How should we and stream to calculate sum of elements?

Using IntStream. This method takes a mapper as a parameter, which it uses to do the conversion, then we can call the sum() method to calculate the sum of the stream's elements. In the same fashion, we can use the mapToLong() and mapToDouble() methods to calculate the sums of longs and doubles, respectively.

Can we use same stream twice?

A stream should be operated on (invoking an intermediate or terminal stream operation) only once. A stream implementation may throw IllegalStateException if it detects that the stream is being reused. So the answer is no, streams are not meant to be reused.

Which stream operations are needed to get sum of all even numbers from stream of integer values?

stream(). mapToInt( Integer::intValue ). sum() .


1 Answers

Well, you could with a custom collector, for instance:

double[] res =
    Arrays.stream(doubles)
          .collect(() -> new double[2],
                   (arr, e) -> {arr[0]+=e; arr[1]+=e*e;},
                   (arr1, arr2) -> {arr1[0]+=arr2[0]; arr1[1]+=arr2[1];});

double sum = res[0];
double sumOfSquares = res[1];

but you don't gain much readability in my opinion, so I would stick with the multiple passes solution (or maybe just use a for-loop in this case).

like image 136
Alexis C. Avatar answered Oct 05 '22 23:10

Alexis C.