diff --git a/src/main/java/org/springframework/data/repository/config/DefaultImplementationLookupConfiguration.java b/src/main/java/org/springframework/data/repository/config/DefaultImplementationLookupConfiguration.java index 372715328..1bade3610 100644 --- a/src/main/java/org/springframework/data/repository/config/DefaultImplementationLookupConfiguration.java +++ b/src/main/java/org/springframework/data/repository/config/DefaultImplementationLookupConfiguration.java @@ -82,7 +82,7 @@ class DefaultImplementationLookupConfiguration implements ImplementationLookupCo */ @Override public Streamable getExcludeFilters() { - return config.getExcludeFilters().and(Streamable.of(new AnnotationTypeFilter(NoRepositoryBean.class))); + return config.getExcludeFilters().and(new AnnotationTypeFilter(NoRepositoryBean.class)); } /* diff --git a/src/main/java/org/springframework/data/util/Streamable.java b/src/main/java/org/springframework/data/util/Streamable.java index a64e33c23..35eed8746 100644 --- a/src/main/java/org/springframework/data/util/Streamable.java +++ b/src/main/java/org/springframework/data/util/Streamable.java @@ -17,6 +17,8 @@ package org.springframework.data.util; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; @@ -146,6 +148,47 @@ public interface Streamable extends Iterable, Supplier> { return Streamable.of(() -> Stream.concat(this.stream(), stream.get())); } + /** + * Creates a new {@link Streamable} from the current one and the given values concatenated. + * + * @param others must not be {@literal null}. + * @return will never be {@literal null}. + * @since 2.2 + */ + @SuppressWarnings("unchecked") + default Streamable and(T... others) { + + Assert.notNull(others, "Other values must not be null!"); + + return Streamable.of(() -> Stream.concat(this.stream(), Arrays.stream(others))); + } + + /** + * Creates a new {@link Streamable} from the current one and the given {@link Iterable} concatenated. + * + * @param iterable must not be {@literal null}. + * @return will never be {@literal null}. + * @since 2.2 + */ + default Streamable and(Iterable iterable) { + + Assert.notNull(iterable, "Iterable must not be null!"); + + return Streamable.of(() -> Stream.concat(this.stream(), StreamSupport.stream(iterable.spliterator(), false))); + } + + /** + * Convenience method to allow adding a {@link Streamable} directly as otherwise the invocation is ambiguous between + * {@link #and(Iterable)} and {@link #and(Supplier)}. + * + * @param streamable must not be {@literal null}. + * @return will never be {@literal null}. + * @since 2.2 + */ + default Streamable and(Streamable streamable) { + return and((Supplier>) streamable); + } + /** * Creates a new, unmodifiable {@link List}. * diff --git a/src/test/java/org/springframework/data/util/StreamableUnitTests.java b/src/test/java/org/springframework/data/util/StreamableUnitTests.java index b6715a158..072a28220 100644 --- a/src/test/java/org/springframework/data/util/StreamableUnitTests.java +++ b/src/test/java/org/springframework/data/util/StreamableUnitTests.java @@ -38,4 +38,19 @@ public class StreamableUnitTests { assertThat(streamable.toList()).containsExactly(1, 2, 1); assertThat(streamable.toSet()).containsExactlyInAnyOrder(1, 2); } + + @Test // DATACMNS-1433 + public void concatenatesIterable() { + assertThat(Streamable.of(1, 2).and(Arrays.asList(3, 4))).containsExactly(1, 2, 3, 4); + } + + @Test // DATACMNS-1433 + public void concatenatesVarargs() { + assertThat(Streamable.of(1, 2).and(3, 4)).containsExactly(1, 2, 3, 4); + } + + @Test // DATACMNS-1433 + public void concatenatesStreamable() { + assertThat(Streamable.of(1, 2).and(Streamable.of(3, 4))).containsExactly(1, 2, 3, 4); + } }