Merge pull request #12505 from thibaultfaure/articles/BAEL-5663-filter-java-stream-to-only-one-element
BAEL-5663 code for the filter java stream to only one element article
This commit is contained in:
commit
c0d5df745e
|
@ -43,6 +43,16 @@
|
|||
<version>3.23.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-core</artifactId>
|
||||
<version>${jmh-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjdk.jmh</groupId>
|
||||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>${jmh-generator.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.streams.filteronlyoneelement;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.infra.Blackhole;
|
||||
|
||||
public class BenchmarkRunner {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
org.openjdk.jmh.Main.main(args);
|
||||
}
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
public static class MyState {
|
||||
final Stream<Integer> getIntegers() {
|
||||
return IntStream.range(1, 1000000)
|
||||
.boxed();
|
||||
}
|
||||
|
||||
final Predicate<Integer> PREDICATE = i -> i == 751879;
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void evaluateFindUniqueElementMatchingPredicate_WithReduction(Blackhole blackhole, MyState state) {
|
||||
blackhole.consume(FilterUtils.findUniqueElementMatchingPredicate_WithReduction(state.getIntegers(), state.PREDICATE));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void evaluateFindUniqueElementMatchingPredicate_WithCollectingAndThen(Blackhole blackhole, MyState state) {
|
||||
blackhole.consume(FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(state.getIntegers(), state.PREDICATE));
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void evaluateGetUniqueElementMatchingPredicate_WithReduction(Blackhole blackhole, MyState state) {
|
||||
try {
|
||||
FilterUtils.getUniqueElementMatchingPredicate_WithReduction(state.getIntegers(), state.PREDICATE);
|
||||
} catch (IllegalStateException exception) {
|
||||
blackhole.consume(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void evaluateGetUniqueElementMatchingPredicate_WithCollectingAndThen(Blackhole blackhole, MyState state) {
|
||||
try {
|
||||
FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(state.getIntegers(), state.PREDICATE);
|
||||
} catch (IllegalStateException exception) {
|
||||
blackhole.consume(exception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.streams.filteronlyoneelement;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class FilterUtils {
|
||||
|
||||
public static <T> Optional<T> findUniqueElementMatchingPredicate_WithReduction(Stream<T> elements, Predicate<T> predicate) {
|
||||
return elements.filter(predicate)
|
||||
.collect(Collectors.reducing((a, b) -> null));
|
||||
}
|
||||
|
||||
public static <T> T getUniqueElementMatchingPredicate_WithReduction(Stream<T> elements, Predicate<T> predicate) {
|
||||
return elements.filter(predicate)
|
||||
.reduce((a, b) -> {
|
||||
throw new IllegalStateException("Too many elements match the predicate");
|
||||
})
|
||||
.orElseThrow(() -> new IllegalStateException("No element matches the predicate"));
|
||||
}
|
||||
|
||||
public static <T> Optional<T> findUniqueElementMatchingPredicate_WithCollectingAndThen(Stream<T> elements, Predicate<T> predicate) {
|
||||
return elements.filter(predicate)
|
||||
.collect(Collectors.collectingAndThen(Collectors.toList(), list -> Optional.ofNullable(findUniqueElement(list))));
|
||||
}
|
||||
|
||||
private static <T> T findUniqueElement(List<T> elements) {
|
||||
if (elements.size() == 1) {
|
||||
return elements.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T getUniqueElementMatchingPredicate_WithCollectingAndThen(Stream<T> elements, Predicate<T> predicate) {
|
||||
return elements.filter(predicate)
|
||||
.collect(Collectors.collectingAndThen(Collectors.toList(), FilterUtils::getUniqueElement));
|
||||
}
|
||||
|
||||
private static <T> T getUniqueElement(List<T> elements) {
|
||||
if (elements.size() > 1) {
|
||||
throw new IllegalStateException("Too many elements match the predicate");
|
||||
} else if (elements.size() == 0) {
|
||||
throw new IllegalStateException("No element matches the predicate");
|
||||
}
|
||||
return elements.get(0);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.baeldung.streams.filteronlyoneelement;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class FilterUtilsUnitTest {
|
||||
|
||||
private static final Predicate<Integer> IS_STRICTLY_GREATER_THAN5 = i -> i > 5;
|
||||
private static final Predicate<Integer> IS_STRICTLY_GREATER_THAN4 = i -> i > 4;
|
||||
private static final Predicate<Integer> IS_STRICTLY_GREATER_THAN3 = i -> i > 3;
|
||||
|
||||
private Stream getIntegers() {
|
||||
return Stream.of(1, 2, 3, 4, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNoElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenNoneFound() {
|
||||
assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN5)
|
||||
.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTwoElementsMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenEmpty() {
|
||||
assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN3)
|
||||
.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenFindsIt() {
|
||||
assertEquals(5, FilterUtils.findUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN4)
|
||||
.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNoElementMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithReduction_ThenThrows() {
|
||||
assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTwoElementsMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithReduction_ThenThrows() {
|
||||
assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithReduction_ThenGetIt() {
|
||||
assertEquals(5, FilterUtils.getUniqueElementMatchingPredicate_WithReduction(getIntegers(), IS_STRICTLY_GREATER_THAN4));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNoElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenEmpty() {
|
||||
assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN5)
|
||||
.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTwoElementsMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenEmpty() {
|
||||
assertTrue(FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN3)
|
||||
.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenFindsIt() {
|
||||
assertEquals(5, FilterUtils.findUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN4)
|
||||
.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenNoElementMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithCollectingAndThen_ThenThrows() {
|
||||
assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN5));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTwoElementsMatchingPredicate_WhenGetUniqueElementMatchingPredicateWithCollectingAndThen_ThenThrows() {
|
||||
assertThrows(IllegalStateException.class, () -> FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN3));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOnlyOneElementMatchingPredicate_WhenFindUniqueElementMatchingPredicateWithCollectingAndThen_ThenGetIt() {
|
||||
assertEquals(5, FilterUtils.getUniqueElementMatchingPredicate_WithCollectingAndThen(getIntegers(), IS_STRICTLY_GREATER_THAN4));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue