1. Overview
Enumeration is an interface from the first version of Java (JDK 1.0). This interface is generic and provides lazy access to a sequence of elements. Although there are better alternatives in newer versions of Java, legacy implementations may still return results using the Enumeration interface. Therefore, for modernizing a legacy implementation, a developer may have to convert an Enumeration object to the Java Stream API.
In this short tutorial, we're going to implement a utility method for converting Enumeration objects to the Java Stream API. As a result, we'll be able to use stream methods such as filter and map.
2. Java's Enumeration Interface
Let's start with an example to illustrate the use of an Enumeration object:
public static <T> void print(Enumeration<T> enumeration) {
while (enumeration.hasMoreElements()) {
System.out.println(enumeration.nextElement());
}
}
Enumeration has two main methods: hasMoreElements and nextElement. We should use both methods together to iterate over the collection of elements.
3. Creating a Spliterator
As a first step, we'll create a concrete class for the AbstractSpliterator abstract class. This class is necessary for adapting the Enumeration objects to the Spliterator interface:
public class EnumerationSpliterator<T> extends AbstractSpliterator<T> {
private final Enumeration<T> enumeration;
public EnumerationSpliterator(long est, int additionalCharacteristics, Enumeration<T> enumeration) {
super(est, additionalCharacteristics);
this.enumeration = enumeration;
}
}
Besides creating the class, we also need to create a constructor. We should pass the first two parameters to the super constructor. The first parameter is the estimated size of the Spliterator. The second one is for defining additional characteristics. Finally, we'll use the last parameter to receive the Enumeration object.
We also need to override the tryAdvance and forEachRemaining methods. They'll be used by the Stream API for performing actions on the Enumeration‘s elements:
@Override
public boolean tryAdvance(Consumer<? super T> action) {
if (enumeration.hasMoreElements()) {
action.accept(enumeration.nextElement());
return true;
}
return false;
}
@Override
public void forEachRemaining(Consumer<? super T> action) {
while (enumeration.hasMoreElements())
action.accept(enumeration.nextElement());
}
4. Converting Enumeration to Stream
Now, using the EnumerationSpliterator class, we're able to use the StreamSupport API for performing the conversion:
public static <T> Stream<T> convert(Enumeration<T> enumeration) {
EnumerationSpliterator<T> spliterator
= new EnumerationSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED, enumeration);
Stream<T> stream = StreamSupport.stream(spliterator, false);
return stream;
}
In this implementation, we need to create an instance of the EnumerationSpliterator class. Long.MAX_VALUE is the default value for the estimated size. Spliterator.ORDERED defines that the stream will iterate the elements in the order provided by the enumeration.
Next, we should call the stream method from the StreamSupport class. We need to pass the EnumerationSpliterator instance as the first parameter. The last parameter is to define whether the stream will be parallel or sequential.
5. Testing Our Implementation
By testing our convert method, we can observe that now we're able to create a valid Stream object based on an Enumeration:
@Test
public void givenEnumeration_whenConvertedToStream_thenNotNull() {
Vector<Integer> input = new Vector<>(Arrays.asList(1, 2, 3, 4, 5));
Stream<Integer> resultingStream = convert(input.elements());
Assert.assertNotNull(resultingStream);
}
6. Conclusion
In this tutorial, we showed how to convert an Enumeration into a Stream object. The source code, as always, can be found over on GitHub.
The post Convert a Java Enumeration Into a Stream first appeared on Baeldung.