Java 8 reduce code example

Understanding Java 8 Reduce function

 

Reduce is one of the most important functionalities which help us in writing Pure functional code. How reduce can help while evaluating the sum of elements in a Integral List

 

Code

  • List Of integers

 

// which is same as IntStream.range(1,5)
 List integerList = Arrays.asList(1, 2, 3, 4);

 

  • Calculate sum by doing imperative style of coding.

 

int sum = 0;        
for (int value : integerList) {
            sum += value;
        }
System.out.println("The sum of the integerList is : " + sum);

The sum of the integerList is : 10

  • Calculate sum by Using stream and Reduce

 

Optional total = integerList.stream()
               // first integer1 the sum from the previous call in the internal iterator
               .reduce((integer1, integer2) -> integer1 + integer2);

System.out.println("Using reduce in Lambda sum is " + total.get());

Using reduce in Lambda sum is 10

 

 

Reduce comes in three variations

 

  • Optional reduce(BinaryOperator accumulator);
  • T reduce(T identity, BinaryOperator accumulator);
  • U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator combiner) used with streams
  • U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator combiner) used with parallelStream

 

[addToAppearHere]

  • Optional reduce(BinaryOperator accumulator) and Understanding internal loop of Reduce :

 

 
 // Lets understand what integer1 reflects
 Optional total1 = integerList.stream()
      // first integer1 the sum from the previous call in the internal iterator
               .reduce((integer1, integer2) -> {
 System.out.println("value of integer1  is  " + integer1 + "  Integer2 is  " + integer2);
                      return integer1 + integer2;
                });

System.out.println("Using reduce in Lambda sum is " + total1.get());

value of integer1 is 1 Integer2 is 2
value of integer1 is 3 Integer2 is 3
value of integer1 is 6 Integer2 is 4
Using reduce in Lambda sum is 10

  • T reduce(T identity, BinaryOperator accumulator) : What if we want the base Sum to be 100

 

Integer total3 = integerList.stream()
       // first integer1 the sum from the previous call in the internal iterator
                .reduce(100, (integer1, integer2) ->
                {
      System.out.println("value of integer1 is " + integer1 + " Integer2 is " + integer2);
                     return integer1 + integer2;
                 }
           );

System.out.println("Using reduce in Lambda with base = 100 sum is " + total3);

Using reduce in Lambda with base = 100 sum is 110


[addToAppearHere]
  • U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator combiner)    No combiner is called when one uses streams.

 

 

  Integer total4 = integerList.stream()
            // first integer1 the sum from the previous call in the internal iterator
            .reduce(
                     //Initial Value
                 100,
                    //Accumulate
                (integer1, integer2) -> {
  System.out.println("value inside accumulate of integer1  is "  
                                + integer1 + "  Integer2 is  " + integer2);
                               return integer1 + integer2;},
                    //Combine
                (integer, integer2) -> {
  System.out.println("value inside combiner of integer1  is " 
                               + integer + "  Integer2 is   "  integer2);
                        return (integer > integer2 ? integer : integer2); }
                    );

System.out.println("Using reduce in Lambda with base = 100 sum is " + total4);


value inside accumulate of integer1  is 100  Integer2 is      1
value inside accumulate of integer1  is 101  Integer2 is      2
value inside accumulate of integer1  is 103  Integer2 is      3
value inside accumulate of integer1  is 106  Integer2 is      4
Using reduce in Lambda with base = 100 sum is 110

  • U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator combiner) and parallelStream combiner is called when one uses  parallelStream.

 

This is like Map Reduce Paradigm (Scatter and gather pattern)

Integer total4 = integerList.parallelStream()
         // first integer1 the sum from the previous call in the internal iterator
                .reduce(
                        //Initial Value
                    100,
                        
                        // Accumulate
                    (integer1, integer2) -> {
  System.out.println("value inside accumulate of integer1  is "
                             + integer1 + "  Integer2 is  " + integer2);
                             return integer1 + integer2;},
                       
                         //Combine
                    (integer, integer2) -> {
 System.out.println("value inside combiner of integer1  is " 
                              + integer + "  Integer2 is   "  integer2);
                              return (integer > integer2 ? integer : integer2);}
                     );

System.out.println("Using reduce in Lambda with base = 100 sum is " + total4);


value inside accumulate of integer1 is 100 Integer2 is 3
value inside accumulate of integer1 is 100 Integer2 is 4
value inside combiner of integer1 is 103 Integer2 is 104
value inside accumulate of integer1 is 100 Integer2 is 2
value inside accumulate of integer1 is 100 Integer2 is 1
value inside combiner of integer1 is 101 Integer2 is 102
value inside combiner of integer1 is 102 Integer2 is 104
Using reduce in Lambda with base = 100 sum is 104