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