I’m going to describe another useful method from **Stream** package. The reduce method is called on a **stream **and returns us some value. For instance, we have a range from 1 to 15 and using functional like approach we can easily get a sum of all the numbers within range, multiplying each element (except the first one – I will explain why, in the next paragraph) by 3 using **reduce **method.

package app; import java.util.stream.IntStream; public class StreamsReduceExample { public static void main(String[] args) { int theSum = IntStream.rangeClosed(1,15) .reduce((x,y) -> x+3*y).orElse(0); System.out.println(theSum); } }

Output:

358

The **reduce **method from **IntStream **class has two overloaded versions: `OptionalInt reduce(IntBinaryOperator op)`

and `int reduce(int identity, IntBinaryOperator op)`

The first one takes an **IntBinaryOperator **which means it takes two parameters and has one output parameter (more on that matter you can read in my article about Functions). The method returns and **OptionalInt ** that’s why I had to call **orElse(0) **to get an **int **value – if the stream was empty, it would have given us **0.**

In the given example the **reduce **method took a function **(x, y) -> x+3*y **as a parameter and returned an **OptionalInt **from which I ‘took’ an **int.**

**Functions – accumulators and cycles**

Here, let me tell you a little bit about what happened under the hood and how the calculations were carried out. This is an approach borrowed from functional languages like eg. **Scala **or **Ruby **(a functional programming paradigm langs). I will also explain why the first value in the given example was not tripled.

The method `OptionalInt reduce(IntBinaryOperator op) `

takes IntBinaryOperator as a parameter. I have passed there **(x, y) -> x+3*y** so in the first iteration variable **x **took the value 1 (first from the range) and **y **took 2. But according to the function I created: **x+3*y** – it’s only the second variable that is multiplied by 3. The first one **x** is the **accumulator **which stores the result of binary operator while **y **takes next values given by the stream.

Here I will show you how the function works by printing out each step:

int theSumWithPrinting = IntStream.rangeClosed(1, 15) .reduce((x, y) -> { System.out.printf("accumulator x=%d, next value y=%d\n", x, y); return x + y * 3; }).orElse(0); System.out.println("Result: " + theSumWithPrinting);

Output:

accumulator x=1, next value y=2 accumulator x=7, next value y=3 accumulator x=16, next value y=4 accumulator x=28, next value y=5 accumulator x=43, next value y=6 accumulator x=61, next value y=7 accumulator x=82, next value y=8 accumulator x=106, next value y=9 accumulator x=133, next value y=10 accumulator x=163, next value y=11 accumulator x=196, next value y=12 accumulator x=232, next value y=13 accumulator x=271, next value y=14 accumulator x=313, next value y=15 Result: 358

I hope it started to make sense now 🙂 Look at the changed code also. I have added printing method to the function and used key word **return **to return the value. This is regular method so you can execute (almost) any code as long as you return value of correct type (in this case an **int**).

Because of the fact that the first element was not taken under consideration we have an overloaded method `int reduce(int identity, IntBinaryOperator op)`

that I mentioned at the beginning. It takes additional **identity **parameter and uses it as the first value so that the first value provided by the stream is tripled. This method returns us **int **value so I can remove **orElse(0) **call.

Example:

int theSumWithPrinting = IntStream.rangeClosed(1, 15) .reduce(0, (x, y) -> { System.out.printf("accumulator x=%d, next value y=%d\n", x, y); return x + y * 3; }); System.out.println("Result: " + theSumWithPrinting);

Output: accumulator x=0, next value y=1 accumulator x=3, next value y=2 accumulator x=9, next value y=3 accumulator x=18, next value y=4 accumulator x=30, next value y=5 accumulator x=45, next value y=6 accumulator x=63, next value y=7 accumulator x=84, next value y=8 accumulator x=108, next value y=9 accumulator x=135, next value y=10 accumulator x=165, next value y=11 accumulator x=198, next value y=12 accumulator x=234, next value y=13 accumulator x=273, next value y=14 accumulator x=315, next value y=15 Result: 360

One last example. We can use built-in methods to sum or find max value of given stream:

int theMinValueUsingStaticReference = IntStream.of(2,45,2,0,102,34,99) .reduce(Integer.MIN_VALUE, Integer::max); System.out.println("Result: " + theMinValueUsingStaticReference); int theSumValueUsingStaticReference = IntStream.of(2,45,2,0,102,34,34,5,43,2) .reduce(0, Integer::sum); System.out.println("Result: " + theSumValueUsingStaticReference);

Output:

Result: 102 Result: 269

That would be it when it comes to basics of the **reduce **method.

Should you have any questions, don’t hesitate to reach me via linkedin, facebook, email or via comments.

If you want to know more visit: https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html – Oracle documentation website.

Let’s code!

Article featured image by:

“Reduce Key” by Got Credit is licensed under CC BY 2.0

that’s a nice one!