diff --git a/src/main/java/org/springframework/data/util/Streamable.java b/src/main/java/org/springframework/data/util/Streamable.java index 35eed8746..fc98467b1 100644 --- a/src/main/java/org/springframework/data/util/Streamable.java +++ b/src/main/java/org/springframework/data/util/Streamable.java @@ -19,9 +19,13 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -216,4 +220,33 @@ public interface Streamable extends Iterable, Supplier> { default Stream get() { return stream(); } + + /** + * A collector to easily produce a {@link Streamable} from a {@link Stream} using {@link Collectors#toList} as + * intermediate collector. + * + * @return + * @see #toStreamable(Collector) + * @since 2.2 + */ + public static Collector> toStreamable() { + return toStreamable(Collectors.toList()); + } + + /** + * A collector to easily produce a {@link Streamable} from a {@link Stream} and the given intermediate collector. + * + * @return + * @since 2.2 + */ + @SuppressWarnings("unchecked") + public static > Collector> toStreamable( + Collector intermediate) { + + return Collector.of( // + (Supplier) intermediate.supplier(), // + (BiConsumer) intermediate.accumulator(), // + (BinaryOperator) intermediate.combiner(), // + Streamable::of); + } } diff --git a/src/test/java/org/springframework/data/util/StreamableUnitTests.java b/src/test/java/org/springframework/data/util/StreamableUnitTests.java index 072a28220..a14b40890 100644 --- a/src/test/java/org/springframework/data/util/StreamableUnitTests.java +++ b/src/test/java/org/springframework/data/util/StreamableUnitTests.java @@ -18,6 +18,7 @@ package org.springframework.data.util; import static org.assertj.core.api.Assertions.*; import java.util.Arrays; +import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.Test; @@ -53,4 +54,16 @@ public class StreamableUnitTests { public void concatenatesStreamable() { assertThat(Streamable.of(1, 2).and(Streamable.of(3, 4))).containsExactly(1, 2, 3, 4); } + + @Test // DATACMNS-1447 + public void usesStreamableCollectors() { + + assertThat(Streamable.of(1, 2).stream() // + .collect(Streamable.toStreamable())) // + .containsExactly(1, 2); + + assertThat(Streamable.of(1, 2, 2).stream() // + .collect(Streamable.toStreamable(Collectors.toSet()))) // + .containsExactlyInAnyOrder(1, 2); + } }