$show=/label

Java 8 Stream reduce

SHARE:

A quick guide to reduce() method from java 8 stream api with examples.

1. Overview

In this tutorial, We'll learn how to use reduce() method to produce the final result from the stream in java 8.

Stream API is added in java 8 and now reduce operation is heavily used by the developers.

reduce() method is a terminal operation of streams.

Java 8 Stream reduce



2. Stream.reduce() Syntax


reduce() method performs the reduction operation on the stream and returns a single value wrapping inside Optional.

reduce() is an overloaded method with different types of arguments to handle the different use cases.
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)


3. Java Stream reduce() Arguments


reduce() methods take 3 arguments at most and they are accumulator, identity and Combiner.

accumulator: This takes two arguments. The first argument stores the partial result of the reduce operation and the second argument stores the next value from the stream.

identity: This is the initial value of the reduce operation. Most of it starts with the default value of stream value type. If we want to start with non default value then we need to use identity.

combiner: If you have an idea about Hadoop map reduce jobs then you may have an idea of the usage of the combiner. But, if you do not know about the map reduce then do not worry. we will learn this with the example program.

When the stream execution is parallel then we might have to use the reduce() combiner option to speed up and collect the intermediate reduce results then pass them to the combiner logic.

In most cases, reduction accumulator logic and combiner logic is the same.


4. Stream reduce() examples


First, understand the example of reduce() method with only accumulator logic.

We use the reduce() method with only one argument that is an accumulator.

Example 1
package com.javaprogramto.java8.streams.reduce;

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

public class StreamReduceExample {

	public static void main(String[] args) {

		List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

		Optional<Integer> sumOptional = numbers.stream().reduce((currentSum, nextValue) -> currentSum + nextValue);

		if(sumOptional.isPresent()) {
			System.out.println("sum of first 7 numbers is "+sumOptional.get());
		}
	}

}

Output:

sum of first 7 numbers is 28


Here the numbers list has values from 1 to 7 and performed the addition of all numbers of list using reduce() function.

reduce accumulator first argument took the current sum and 2nd argument holds next value from the stream.

look at the each step of itreation of reduce() method with currentSum and nextValue.
currentSum nextValue
  0                      1
  1                      2
  3                      3
  6                      4
  10                    5
  15                    6
  21                    7
  28 is return as optional object.



5. Stream reduce() example with initial value


Sometimes we may need to pass the initial value to the reduce operation. In that case, we need to use the identity argument of reduce() function.

We use now the reduce() method with 2 arguments and that identity and accumulator.

Example 2

In this example, create the list with only 3 values and those values are 8, 9, 10.

Now, we need to find the sum of the first 10 numbers but the list has only 3 numbers from 8 to 10. The remaining numbers from 1 to 7 are missing. So, we are storing the sum of 1 to 7 is 28 in the integer variable.

Now we pass this integer to reduce the method to start the sum from 28 rather than 0 as the default value.

Look at the below example.
package com.javaprogramto.java8.streams.reduce;

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

public class StreamReduceExample2 {

	public static void main(String[] args) {

		Integer sumOf1to7 = 28;

		List<Integer> numbers = Arrays.asList(8, 9, 10);

		Integer sum = numbers.stream().reduce(sumOf1to7, (currentSum, nextValue) -> currentSum + nextValue);

		System.out.println("sum of first 10 numbers is " + sum);
	}

}

Output:
sum of first 10 numbers is 55

In the output, we are seeing the sum is 55 which is a sum of first 10 numbers using reduce() default value option.

In this case, reduce() method does not return the Optional instance rather than it returns the type of identity or default value or initial value type. Because the initial value will be with some value always. If the default value is null then it is not suggested to use reduce identity method. You need to use the reduce with the accumulator only.


5. Stream reduce() Parallel example with Combiner


Next, we use reduce() method 3 arguments - identity, accumulator and combiner.

Example 3

Look at the below example stream is sequential, with and without combiner usage.

package com.javaprogramto.java8.streams.reduce;

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

public class StreamReduceExample3 {

	public static void main(String[] args) {

		Integer sumOf1to2 = 3;

		List<Integer> numbers = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10);

		Integer sum = numbers.stream().reduce(sumOf1to2, (currentSum, nextValue) -> currentSum + nextValue);

		System.out.println("Without combiner - sum of first 10 numbers is " + sum);

		Integer sumWithCombiner = numbers.stream().reduce(sumOf1to2, (currentSum, nextValue) -> currentSum + nextValue,
				Integer::sum);

		System.out.println("With Combiner - sum of first 10 numbers is " + sumWithCombiner);

	}
}

Output

Without combiner - sum of first 10 numbers is 55
With Combiner - sum of first 10 numbers is 55

Output is the same when the stream is executed in sequential.

Note: When the stream is not parallel then no need of using a combiner in the reduce() operation.

Let us use reduce() method with the parallel streams with and without combiner.

Example 4

In this example, we are getting the addition of the first 100 million numbers with sequential and parallel streams using reduce combiner logic.


This is quite huge processing and you can see the performance benchmarks.
package com.javaprogramto.java8.streams.reduce;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class StreamReduceExample4 {

	public static void main(String[] args) {

		Integer identity = 0;

		
		IntStream numbers = IntStream.iterate(1, i -> i + 1);

		List<Integer> numList = numbers.limit(100000000).boxed().collect(Collectors.toList());

		long l1 = System.currentTimeMillis();
		Integer sum = numList.stream().reduce(identity, (currentSum, nextValue) -> currentSum + nextValue, Integer::sum);
		long l2 = System.currentTimeMillis();
		System.out.println("With sequential stream sum is " + sum + " in " + (l2 - l1) + " ms");

		
		long l3 = System.currentTimeMillis();
		Integer sumWithCombiner = numList.stream().parallel().reduce(identity,
				(currentSum, nextValue) -> currentSum + nextValue, Integer::sum);
		long l4 = System.currentTimeMillis();
		
		System.out
				.println("With parallel stream sum is " + sumWithCombiner + " in " + (l4 - l3) + " ms");

	}
}


Output:
With sequential stream sum is 987459712 in 1861 ms
With parallel stream sum is 987459712 in 549 ms

Parallel streams took 3 times less execution time than sequential stream execution. So, parallel streams are always more performant than normal streams.


6. Stream reduce() exceptional handling


The below program throws the runtime arithmetic exception.

Example 5

package com.javaprogramto.java8.streams.reduce;

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

public class StreamReduceExample5 {

	public static void main(String[] args) {

		List<Integer> numbers = Arrays.asList(1, 2, 3, 0, 5, 6, 7);

		Optional<Integer> division = numbers.stream().reduce((currentSum, nextValue) -> currentSum / nextValue);

		if (division.isPresent()) {
			System.out.println("division of first 7 numbers is " + division.get());
		}
	}
}

Output
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.javaprogramto.java8.streams.reduce.StreamReduceExample5.lambda$0(StreamReduceExample5.java:13)
	at java.base/java.util.stream.ReduceOps$2ReducingSink.accept(ReduceOps.java:123)
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:558)
	at com.javaprogramto.java8.streams.reduce.StreamReduceExample5.main(StreamReduceExample5.java:13)


To handle arithmetic exception, we need to add the try-catch inside the lambda expression as below. But the code does not look clean.

Example 6

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

import org.slf4j.Logger;


public class StreamReduceExample5 {
	
	static Logger log = org.slf4j.LoggerFactory.getLogger(StreamReduceExample5.class);

	public static void main(String[] args) {

		List<Integer> numbers = Arrays.asList(1, 2, 3, 0, 5, 6, 7);

		Optional<Integer> division = numbers.stream().reduce((currentSum, nextValue) -> {
			int div = 0;
			try {
			div = currentSum / nextValue;
			} catch (ArithmeticException e) {
				log.error("arithmetic exception thrown");
			}
			return div;
		});

		if (division.isPresent()) {
			System.out.println("division of first 7 numbers is " + division.get());
		}
	}
}

To make the code cleaner, we need to use the separate utility method and call the method from lambda.

Example 7

public class StreamReduceExample6 {

	static Logger log = org.slf4j.LoggerFactory.getLogger(StreamReduceExample5.class);

	public static void main(String[] args) {

		List<Integer> numbers = Arrays.asList(1, 2, 3, 0, 5, 6, 7);

		Optional<Integer> division = numbers.stream().reduce((currentSum, nextValue) -> doDivision(currentSum, nextValue));

		if (division.isPresent()) {
			System.out.println("division of first 7 numbers is " + division.get());
		}
	}

	private static int doDivision(Integer currentSum, Integer nextValue) {
		int div = 0;
		try {
			div = currentSum / nextValue;

		} catch (ArithmeticException e) {
			log.error("arithmetic exception thrown");
		}
		return div;
	}
}



7. Stream reduce() - with custom objects


reduce() method can work with custom complex objects.

Example 8

package com.javaprogramto.java8.streams.reduce;

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

import com.javaprogramto.java8.compare.Employee;

public class StreamReduceExample7 {

	public static void main(String[] args) {

		List<Employee> empList = Arrays.asList(new Employee(100, "A", 20), new Employee(200, "B", 30),
				new Employee(300, "C", 40));

		Integer ageSum = empList.stream().map(emp -> emp.getAge()).reduce(new Employee(400, "new emp", 60).getAge(),
				(age1, age2) -> age1 + age2);

		System.out.println("age sum - " + ageSum);

	}

}

Output
age sum - 150


8. Conclusion


In this article, We've seen in-depth about stream reduce() method in java 8.




COMMENTS

BLOGGER

About Us

Author: Venkatesh - I love to learn and share the technical stuff.
Name

accumulo,1,ActiveMQ,2,Adsense,1,API,37,ArrayList,18,Arrays,21,Bean Creation,3,Bean Scopes,1,BiConsumer,1,Blogger Tips,1,Books,1,C Programming,1,Collection,8,Collections,32,Collector,1,Command Line,1,Compile Errors,1,Configurations,7,Constants,1,Control Statements,8,Conversions,6,Core Java,135,Corona India,1,Create,2,CSS,1,Date,3,Date Time API,38,Dictionary,1,Difference,2,Download,1,Eclipse,3,Efficiently,1,Error,1,Errors,1,Exceptions,7,Fast,1,Files,17,Float,1,Font,1,Form,1,Freshers,1,Function,3,Functional Interface,2,Garbage Collector,1,Generics,4,Git,9,Grant,1,Grep,1,HashMap,2,HomeBrew,2,HTML,2,HttpClient,2,Immutable,1,Installation,1,Interview Questions,6,Iterate,2,Jackson API,3,Java,32,Java 10,1,Java 11,6,Java 12,5,Java 13,2,Java 14,2,Java 8,127,Java 8 Difference,2,Java 8 Stream Conversions,4,java 8 Stream Examples,12,Java 9,1,Java Conversions,14,Java Design Patterns,1,Java Files,1,Java Program,3,Java Programs,113,Java Spark,1,java.lang,4,java.util. function,1,JavaScript,1,jQuery,1,Kotlin,11,Kotlin Conversions,6,Kotlin Programs,10,Lambda,2,lang,29,Leap Year,1,live updates,1,LocalDate,1,Logging,1,Mac OS,3,Math,1,Matrix,6,Maven,1,Method References,1,Mockito,1,MongoDB,3,New Features,1,Operations,1,Optional,6,Oracle,5,Oracle 18C,1,Partition,1,Patterns,1,Programs,1,Property,1,Python,2,Quarkus,1,Read,1,Real Time,1,Recursion,2,Remove,2,Rest API,1,Schedules,1,Serialization,1,Servlet,2,Sort,1,Sorting Techniques,8,Spring,2,Spring Boot,23,Spring Email,1,Spring MVC,1,Streams,29,String,61,String Programs,28,String Revese,1,Swing,1,System,1,Tags,1,Threads,11,Tomcat,1,Tomcat 8,1,Troubleshoot,24,Unix,3,Updates,3,util,5,While Loop,1,
ltr
item
JavaProgramTo.com: Java 8 Stream reduce
Java 8 Stream reduce
A quick guide to reduce() method from java 8 stream api with examples.
https://1.bp.blogspot.com/-uDgtEBsnR2I/YZ_ZFAaL6yI/AAAAAAAADjE/VjsToxSieGQdkEYc9J9-4dMCfvtaVVH8ACLcBGAsYHQ/w640-h378/Java%2B8%2BStream%2Breduce.png
https://1.bp.blogspot.com/-uDgtEBsnR2I/YZ_ZFAaL6yI/AAAAAAAADjE/VjsToxSieGQdkEYc9J9-4dMCfvtaVVH8ACLcBGAsYHQ/s72-w640-c-h378/Java%2B8%2BStream%2Breduce.png
JavaProgramTo.com
https://www.javaprogramto.com/2021/11/java-stream-reduce.html
https://www.javaprogramto.com/
https://www.javaprogramto.com/
https://www.javaprogramto.com/2021/11/java-stream-reduce.html
true
3124782013468838591
UTF-8
Loaded All Posts Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS PREMIUM CONTENT IS LOCKED STEP 1: Share to a social network STEP 2: Click the link on your social network Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy Table of Content