Guide to Stream.reduce() (#6480)
* Initial Commit * Update Application.java * Update Application.java
This commit is contained in:
		
							parent
							
								
									c81651ba42
								
							
						
					
					
						commit
						ae6c29dd19
					
				
							
								
								
									
										39
									
								
								java-streams-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								java-streams-2/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |     <modelVersion>4.0.0</modelVersion> | ||||||
|  |     <groupId>com.baeldung.javastreams2</groupId> | ||||||
|  |     <artifactId>javastreams2</artifactId> | ||||||
|  |     <version>1.0</version> | ||||||
|  |     <packaging>jar</packaging> | ||||||
|  |     <dependencies> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.openjdk.jmh</groupId> | ||||||
|  |             <artifactId>jmh-core</artifactId> | ||||||
|  |             <version>1.21</version> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.openjdk.jmh</groupId> | ||||||
|  |             <artifactId>jmh-generator-annprocess</artifactId> | ||||||
|  |             <version>1.21</version> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>junit</groupId> | ||||||
|  |             <artifactId>junit</artifactId> | ||||||
|  |             <version>4.12</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |             <type>jar</type> | ||||||
|  |         </dependency> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>org.assertj</groupId> | ||||||
|  |             <artifactId>assertj-core</artifactId> | ||||||
|  |             <version>3.11.1</version> | ||||||
|  |             <scope>test</scope> | ||||||
|  |         </dependency> | ||||||
|  |     </dependencies> | ||||||
|  |     <name>Stream Reduce</name> | ||||||
|  |     <properties> | ||||||
|  |         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||||
|  |         <maven.compiler.source>1.8</maven.compiler.source> | ||||||
|  |         <maven.compiler.target>1.8</maven.compiler.target> | ||||||
|  |     </properties> | ||||||
|  | </project> | ||||||
| @ -0,0 +1,39 @@ | |||||||
|  | package com.baeldung.reduce.application; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.reduce.entities.User; | ||||||
|  | import com.baeldung.reduce.utilities.NumberUtils; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | public class Application { | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) { | ||||||
|  |         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); | ||||||
|  |         int result1 = numbers.stream().reduce(0, (subtotal, element) -> subtotal + element); | ||||||
|  |         System.out.println(result1); | ||||||
|  |          | ||||||
|  |         int result2 = numbers.stream().reduce(0, Integer::sum); | ||||||
|  |         System.out.println(result2); | ||||||
|  | 
 | ||||||
|  |         List<String> letters = Arrays.asList("a", "b", "c", "d", "e"); | ||||||
|  |         String result3 = letters.stream().reduce("", (partialString, element) -> partialString + element); | ||||||
|  |         System.out.println(result3); | ||||||
|  |          | ||||||
|  |         String result4 = letters.stream().reduce("", String::concat); | ||||||
|  |         System.out.println(result4); | ||||||
|  | 
 | ||||||
|  |         String result5 = letters.stream().reduce("", (partialString, element) -> partialString.toUpperCase() + element.toUpperCase()); | ||||||
|  |         System.out.println(result5); | ||||||
|  |          | ||||||
|  |         List<User> users = Arrays.asList(new User("John", 30), new User("Julie", 35)); | ||||||
|  |         int result6 = users.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); | ||||||
|  |         System.out.println(result6); | ||||||
|  |          | ||||||
|  |         String result7 = letters.parallelStream().reduce("", String::concat); | ||||||
|  |         System.out.println(result7); | ||||||
|  |          | ||||||
|  |         int result8 = users.parallelStream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); | ||||||
|  |         System.out.println(result8); | ||||||
|  |     }     | ||||||
|  | } | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | package com.baeldung.reduce.benchmarks; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.reduce.entities.User; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import org.openjdk.jmh.annotations.Benchmark; | ||||||
|  | import org.openjdk.jmh.annotations.BenchmarkMode; | ||||||
|  | import org.openjdk.jmh.annotations.Mode; | ||||||
|  | import org.openjdk.jmh.annotations.Scope; | ||||||
|  | import org.openjdk.jmh.annotations.State; | ||||||
|  | import org.openjdk.jmh.runner.Runner; | ||||||
|  | import org.openjdk.jmh.runner.RunnerException; | ||||||
|  | import org.openjdk.jmh.runner.options.Options; | ||||||
|  | import org.openjdk.jmh.runner.options.OptionsBuilder; | ||||||
|  | 
 | ||||||
|  | @State(Scope.Thread) | ||||||
|  | @BenchmarkMode(Mode.AverageTime) | ||||||
|  | public class JMHStreamReduceBenchMark { | ||||||
|  |      | ||||||
|  |     private final List<User> userList = createUsers(); | ||||||
|  | 
 | ||||||
|  |     public static void main(String[] args) throws RunnerException { | ||||||
|  |          | ||||||
|  |         Options options = new OptionsBuilder() | ||||||
|  |                 .include(JMHStreamReduceBenchMark.class.getSimpleName()).threads(1) | ||||||
|  |                 .forks(1).shouldFailOnError(true).shouldDoGC(true) | ||||||
|  |                 .jvmArgs("-server").build(); | ||||||
|  |         new Runner(options).run(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private List<User> createUsers() { | ||||||
|  |         List<User> users = new ArrayList<>(); | ||||||
|  |         for (int i = 0; i <= 1000000; i++) { | ||||||
|  |             users.add(new User("John" + i, i)); | ||||||
|  |         } | ||||||
|  |         return users; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Benchmark | ||||||
|  |     public Integer executeReduceOnParallelizedStream() { | ||||||
|  |         return this.userList | ||||||
|  |                 .parallelStream() | ||||||
|  |                 .reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Benchmark | ||||||
|  |     public Integer executeReduceOnSequentialStream() { | ||||||
|  |         return this.userList | ||||||
|  |                 .stream() | ||||||
|  |                 .reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,25 @@ | |||||||
|  | package com.baeldung.reduce.entities; | ||||||
|  | 
 | ||||||
|  | public class User { | ||||||
|  | 
 | ||||||
|  |     private final String name; | ||||||
|  |     private final int age; | ||||||
|  | 
 | ||||||
|  |     public User(String name, int age) { | ||||||
|  |         this.name = name; | ||||||
|  |         this.age = age; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getAge() { | ||||||
|  |         return age; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "User{" + "name=" + name + ", age=" + age + '}'; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | package com.baeldung.reduce.utilities; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.function.BiFunction; | ||||||
|  | import java.util.logging.Level; | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | 
 | ||||||
|  | public abstract class NumberUtils { | ||||||
|  | 
 | ||||||
|  |     private static final Logger LOGGER = Logger.getLogger(NumberUtils.class.getName()); | ||||||
|  | 
 | ||||||
|  |     public static int divideListElements(List<Integer> values, Integer divider) { | ||||||
|  |         return values.stream() | ||||||
|  |                 .reduce(0, (a, b) -> { | ||||||
|  |                     try { | ||||||
|  |                         return a / divider + b / divider; | ||||||
|  |                     } catch (ArithmeticException e) { | ||||||
|  |                         LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); | ||||||
|  |                     } | ||||||
|  |                     return 0; | ||||||
|  |                 }); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public static int divideListElementsWithExtractedTryCatchBlock(List<Integer> values, int divider) { | ||||||
|  |         return values.stream().reduce(0, (a, b) -> divide(a, divider) + divide(b, divider)); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public static int divideListElementsWithApplyFunctionMethod(List<Integer> values, int divider) { | ||||||
|  |         BiFunction<Integer, Integer, Integer> division = (a, b) -> a / b; | ||||||
|  |         return values.stream().reduce(0, (a, b) -> applyFunction(division, a, divider) + applyFunction(division, b, divider)); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private static int divide(int value, int factor) { | ||||||
|  |         int result = 0; | ||||||
|  |         try { | ||||||
|  |             result = value / factor; | ||||||
|  |         } catch (ArithmeticException e) { | ||||||
|  |             LOGGER.log(Level.INFO, "Arithmetic Exception: Division by Zero"); | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     private static int applyFunction(BiFunction<Integer, Integer, Integer> function, int a, int b) { | ||||||
|  |         try { | ||||||
|  |             return function.apply(a, b); | ||||||
|  |         } | ||||||
|  |         catch(Exception e) { | ||||||
|  |             LOGGER.log(Level.INFO, "Exception thrown!"); | ||||||
|  |         } | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,79 @@ | |||||||
|  | package com.baeldung.reduce.tests; | ||||||
|  | 
 | ||||||
|  | import com.baeldung.reduce.entities.User; | ||||||
|  | import com.baeldung.reduce.utilities.NumberUtils; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.List; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | import org.junit.Test; | ||||||
|  | 
 | ||||||
|  | public class StreamReduceUnitTest { | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenIntegerList_whenReduceWithSumAccumulatorLambda_thenCorrect() { | ||||||
|  |         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); | ||||||
|  |         int result = numbers.stream().reduce(0, (subtotal, element) -> subtotal + element); | ||||||
|  |         assertThat(result).isEqualTo(21); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenIntegerList_whenReduceWithSumAccumulatorMethodReference_thenCorrect() { | ||||||
|  |         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); | ||||||
|  |         int result = numbers.stream().reduce(0, Integer::sum); | ||||||
|  |         assertThat(result).isEqualTo(21); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenStringList_whenReduceWithConcatenatorAccumulatorLambda_thenCorrect() { | ||||||
|  |         List<String> letters = Arrays.asList("a", "b", "c", "d", "e"); | ||||||
|  |         String result = letters.stream().reduce("", (partialString, element) -> partialString + element); | ||||||
|  |         assertThat(result).isEqualTo("abcde"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenStringList_whenReduceWithConcatenatorAccumulatorMethodReference_thenCorrect() { | ||||||
|  |         List<String> letters = Arrays.asList("a", "b", "c", "d", "e"); | ||||||
|  |         String result = letters.stream().reduce("", String::concat); | ||||||
|  |         assertThat(result).isEqualTo("abcde"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenStringList_whenReduceWithUppercaseConcatenatorAccumulator_thenCorrect() { | ||||||
|  |         List<String> letters = Arrays.asList("a", "b", "c", "d", "e"); | ||||||
|  |         String result = letters.stream().reduce("", (partialString, element) -> partialString.toUpperCase() + element.toUpperCase()); | ||||||
|  |         assertThat(result).isEqualTo("ABCDE"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenUserList_whenReduceWithAgeAccumulatorAndSumCombiner_thenCorrect() { | ||||||
|  |         List<User> users = Arrays.asList(new User("John", 30), new User("Julie", 35)); | ||||||
|  |         int result = users.stream().reduce(0, (partialAgeResult, user) -> partialAgeResult + user.getAge(), Integer::sum); | ||||||
|  |         assertThat(result).isEqualTo(65); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenStringList_whenReduceWithParallelStream_thenCorrect() { | ||||||
|  |         List<String> letters = Arrays.asList("a", "b", "c", "d", "e"); | ||||||
|  |         String result = letters.parallelStream().reduce("", String::concat); | ||||||
|  |         assertThat(result).isEqualTo("abcde"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenNumberUtilsClass_whenCalledDivideListElements_thenCorrect() { | ||||||
|  |         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); | ||||||
|  |         assertThat(NumberUtils.divideListElements(numbers, 1)).isEqualTo(21); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenNumberUtilsClass_whenCalledDivideListElementsWithExtractedTryCatchBlock_thenCorrect() { | ||||||
|  |         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); | ||||||
|  |         assertThat(NumberUtils.divideListElementsWithExtractedTryCatchBlock(numbers, 1)).isEqualTo(21); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenStream_whneCalleddivideListElementsWithApplyFunctionMethod_thenCorrect() { | ||||||
|  |         List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); | ||||||
|  |         assertThat(NumberUtils.divideListElementsWithApplyFunctionMethod(numbers, 1)).isEqualTo(21); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user