This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-lang.git
commit ff415c8f8f213d40a19f8dc9ac037050ef497bf8 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Thu Nov 18 12:46:31 2021 -0500 Add Streams.nullSafeStream(Collection). Add Streams.toStream(Collection). --- src/changes/changes.xml | 2 + .../org/apache/commons/lang3/stream/Streams.java | 31 +++++++++++-- .../apache/commons/lang3/stream/StreamsTest.java | 51 ++++++++++++++-------- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 852c3dc..01d241c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -97,6 +97,8 @@ The <action> type attribute can be add,update,fix,remove. <action type="add" dev="ggregory" due-to="Gary Gregory">Add and use ClassUtils.isPublic(Class).</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add UncheckedIllegalAccessException.</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add MethodInvokers.</action> + <action type="add" dev="ggregory" due-to="Gary Gregory">Add Streams.nullSafeStream(Collection).</action> + <action type="add" dev="ggregory" due-to="Gary Gregory">Add Streams.toStream(Collection).</action> <!-- UPDATE --> <action type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump spotbugs-maven-plugin from 4.2.0 to 4.4.2.2 #735, #808, #822.</action> <action type="update" dev="ggregory" due-to="Dependabot, XenoAmess">Bump Bump actions/cache from v2.1.4 to v2.1.6 #742, #752, #764.</action> diff --git a/src/main/java/org/apache/commons/lang3/stream/Streams.java b/src/main/java/org/apache/commons/lang3/stream/Streams.java index cd112e7..7cee571 100644 --- a/src/main/java/org/apache/commons/lang3/stream/Streams.java +++ b/src/main/java/org/apache/commons/lang3/stream/Streams.java @@ -446,8 +446,20 @@ public class Streams { } } - private static <O> Stream<O> nullSafeStream(final Collection<O> collection) { - return collection == null ? Stream.empty() : collection.stream(); + private static <E> Stream<E> filter(final Collection<E> collection, final Predicate<? super E> predicate) { + return toStream(collection).filter(predicate); + } + + /** + * Streams non-null elements of a collection. + * + * @param <E> the type of elements in the collection. + * @param collection the collection to stream or null. + * @return A non-null stream that filters out null elements. + * @since 3.13.0 + */ + public static <E> Stream<E> nullSafeStream(final Collection<E> collection) { + return filter(collection, Objects::nonNull); } /** @@ -498,9 +510,10 @@ public class Streams { * @param <O> The streams element type. * @param stream The stream, which is being converted. * @return The {@link FailableStream}, which has been created by converting the stream. + * TODO Rename to failableStream() */ public static <O> FailableStream<O> stream(final Collection<O> stream) { - return stream(nullSafeStream(stream)); + return stream(toStream(stream)); } /** @@ -553,4 +566,16 @@ public class Streams { public static <O extends Object> Collector<O, ?, O[]> toArray(final Class<O> pElementType) { return new ArrayCollector<>(pElementType); } + + /** + * Delegates to {@link Collection#stream()} or returns {@link Stream#empty()} if the collection is null. + * + * @param <E> the type of elements in the collection. + * @param collection the collection to stream or null. + * @return {@link Collection#stream()} or {@link Stream#empty()} if the collection is null. + * @since 3.13.0 + */ + public static <E> Stream<E> toStream(final Collection<E> collection) { + return collection == null ? Stream.empty() : collection.stream(); + } } diff --git a/src/test/java/org/apache/commons/lang3/stream/StreamsTest.java b/src/test/java/org/apache/commons/lang3/stream/StreamsTest.java index 79eeeb8..490799d 100644 --- a/src/test/java/org/apache/commons/lang3/stream/StreamsTest.java +++ b/src/test/java/org/apache/commons/lang3/stream/StreamsTest.java @@ -75,36 +75,30 @@ public class StreamsTest { @TestFactory public Stream<DynamicTest> simpleStreamFilterFailing() { final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6"); - final List<Integer> output = Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(null)) - .collect(Collectors.toList()); + final List<Integer> output = Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(null)).collect(Collectors.toList()); assertEvenNumbers(output); return Stream.of( dynamicTest("IllegalArgumentException", () -> { final IllegalArgumentException iae = new IllegalArgumentException("Invalid argument: " + 5); - final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf) - .filter(asIntPredicate(iae)).collect(Collectors.toList()); + final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(iae)).collect(Collectors.toList()); final IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, testMethod); assertThat(thrown.getMessage(), is(equalTo("Invalid argument: " + 5))); }), dynamicTest("OutOfMemoryError", () -> { final OutOfMemoryError oome = new OutOfMemoryError(); - final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf) - .filter(asIntPredicate(oome)).collect(Collectors.toList()); + final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(oome)).collect(Collectors.toList()); final OutOfMemoryError thrown = assertThrows(OutOfMemoryError.class, testMethod); assertThat(thrown.getMessage(), is(nullValue())); }), dynamicTest("SAXException", () -> { final SAXException se = new SAXException(); - final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf) - .filter(asIntPredicate(se)).collect(Collectors.toList()); - final UndeclaredThrowableException thrown = assertThrows(UndeclaredThrowableException.class, - testMethod); - assertAll(() -> assertThat(thrown.getMessage(), is(nullValue())), - () -> assertThat(thrown.getCause(), is(equalTo(se)))); + final Executable testMethod = () -> Failable.stream(input).map(Integer::valueOf).filter(asIntPredicate(se)).collect(Collectors.toList()); + final UndeclaredThrowableException thrown = assertThrows(UndeclaredThrowableException.class, testMethod); + assertAll(() -> assertThat(thrown.getMessage(), is(nullValue())), () -> assertThat(thrown.getCause(), is(equalTo(se)))); })); } @@ -131,14 +125,25 @@ public class StreamsTest { dynamicTest("SAXException", () -> { final SAXException se = new SAXException(); final Executable seTestMethod = () -> Failable.stream(input).forEach(asIntConsumer(se)); - final UndeclaredThrowableException seThrown = assertThrows(UndeclaredThrowableException.class, - seTestMethod); - assertAll(() -> assertThat(seThrown.getMessage(), is(nullValue())), - () -> assertThat(seThrown.getCause(), is(equalTo(se)))); + final UndeclaredThrowableException seThrown = assertThrows(UndeclaredThrowableException.class, seTestMethod); + assertAll(() -> assertThat(seThrown.getMessage(), is(nullValue())), () -> assertThat(seThrown.getCause(), is(equalTo(se)))); })); } @Test + public void testNullSafeStreamNotNull() { + assertEquals(2, Streams.nullSafeStream(Arrays.asList("A", "B")).collect(Collectors.toList()).size()); + assertEquals(2, Streams.nullSafeStream(Arrays.asList(null, "A", null, "B", null)).collect(Collectors.toList()).size()); + assertEquals(0, Streams.nullSafeStream(Arrays.asList(null, null)).collect(Collectors.toList()).size()); + } + + @Test + public void testNullSafeStreamNull() { + final List<String> input = null; + assertEquals(0, Streams.nullSafeStream(input).collect(Collectors.toList()).size()); + } + + @Test public void testOfArray() { assertEquals(0, Streams.of((Object[]) null).count()); assertEquals(1, Streams.of("foo").count()); @@ -148,8 +153,7 @@ public class StreamsTest { @Test public void testSimpleStreamFilter() { final List<String> input = Arrays.asList("1", "2", "3", "4", "5", "6"); - final List<Integer> output = Failable.stream(input).map(Integer::valueOf).filter(i -> (i.intValue() % 2 == 0)) - .collect(Collectors.toList()); + final List<Integer> output = Failable.stream(input).map(Integer::valueOf).filter(i -> (i.intValue() % 2 == 0)).collect(Collectors.toList()); assertEvenNumbers(output); } @@ -204,4 +208,15 @@ public class StreamsTest { assertEquals("1", array[2]); } + @Test + public void testToStreamNotNull() { + assertEquals(2, Streams.toStream(Arrays.asList("A", "B")).collect(Collectors.toList()).size()); + } + + @Test + public void testToStreamNull() { + final List<String> input = null; + assertEquals(0, Streams.toStream(input).collect(Collectors.toList()).size()); + } + }