From 0bee92719352c658886763618bf4eacc7dc2b7ec Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sat, 16 Jul 2022 09:27:15 -0400 Subject: [PATCH] Add Streams.of(Enumeration) --- src/changes/changes.xml | 1 + .../apache/commons/lang3/stream/Streams.java | 57 +++++++++++++++++++ .../commons/lang3/stream/StreamsTest.java | 16 ++++++ 3 files changed, 74 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 454d5690a..e5e32ada0 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -157,6 +157,7 @@ The type attribute can be add,update,fix,remove. Add SystemUtils.IS_JAVA_18. Add ArrayUtils.oneHot(). Let ReflectionToStringBuilder only reflect given field names #849. + Add Streams.of(Enumeration<E>). Bump actions/cache from 2.1.4 to 3.0.5 #742, #752, #764, #833, #867. Bump actions/checkout from 2 to 3 #819, #825, #859. 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 e44ed7bf0..720405129 100644 --- a/src/main/java/org/apache/commons/lang3/stream/Streams.java +++ b/src/main/java/org/apache/commons/lang3/stream/Streams.java @@ -19,9 +19,12 @@ package org.apache.commons.lang3.stream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.Spliterator; +import java.util.Spliterators.AbstractSpliterator; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Consumer; @@ -31,6 +34,7 @@ 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; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.function.Failable; @@ -122,6 +126,47 @@ public class Streams { } } + /** + * Helps implement {@link Streams#of(Enumeration)}. + * + * @param The element type. + */ + private static class EnumerationSpliterator extends AbstractSpliterator { + + private final Enumeration enumeration; + + /** + * Creates a spliterator reporting the given estimated size and additionalCharacteristics. + * + * @param estimatedSize the estimated size of this spliterator if known, otherwise {@code Long.MAX_VALUE}. + * @param additionalCharacteristics properties of this spliterator's source or elements. If {@code SIZED} is reported then this spliterator will + * additionally report {@code SUBSIZED}. + * @param enumeration The Enumeration to wrap. + */ + protected EnumerationSpliterator(final long estimatedSize, final int additionalCharacteristics, final Enumeration enumeration) { + super(estimatedSize, additionalCharacteristics); + this.enumeration = Objects.requireNonNull(enumeration, "enumeration"); + } + + @Override + public void forEachRemaining(final Consumer action) { + while (enumeration.hasMoreElements()) { + next(action); + } + } + + private boolean next(final Consumer action) { + action.accept(enumeration.nextElement()); + return true; + + } + + @Override + public boolean tryAdvance(final Consumer action) { + return enumeration.hasMoreElements() ? next(action) : false; + } + } + /** * A reduced, and simplified version of a {@link Stream} with failable method signatures. * @@ -572,6 +617,18 @@ public class Streams { return filter(collection, Objects::nonNull); } + /** + * Streams the elements of the given enumeration in order. + * + * @param The enumeration element type. + * @param enumeration The enumeration to stream. + * @return a new stream. + * @since 3.13.0 + */ + public static Stream of(final Enumeration enumeration) { + return StreamSupport.stream(new EnumerationSpliterator<>(Long.MAX_VALUE, Spliterator.ORDERED, enumeration), false); + } + /** * Null-safe version of {@link Stream#of(Object[])}. * 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 625bff4cb..99b34204b 100644 --- a/src/test/java/org/apache/commons/lang3/stream/StreamsTest.java +++ b/src/test/java/org/apache/commons/lang3/stream/StreamsTest.java @@ -24,11 +24,13 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.DynamicTest.dynamicTest; import java.lang.reflect.UndeclaredThrowableException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Hashtable; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -161,6 +163,20 @@ public class StreamsTest extends AbstractLangTest { assertEquals(2, Streams.of("foo", "bar").count()); } + @Test + public void testOfEnumeration() { + final Hashtable table = new Hashtable<>(); + assertEquals(0, Streams.of(table.elements()).count()); + table.put("One", 1); + assertEquals(1, Streams.of(table.elements()).count()); + table.put("Two", 2); + assertEquals(2, Streams.of(table.elements()).count()); + final List collect = Streams.of(table.keys()).collect(Collectors.toList()); + assertTrue(collect.contains("One")); + assertTrue(collect.contains("Two")); + assertEquals(2, collect.size()); + } + @Test public void testSimpleStreamFilter() { final List input = Arrays.asList("1", "2", "3", "4", "5", "6");