How to convert Enumeration to Stream in Java

April 18, 2021 No comments Enumeration Stream Java Convert

1. Introduction

The Enumeration is an interface that was introduced in an older version of Java and is used to store a sequence of elements. An object that implements that interface generates a series of elements, one at a time. Calling the nextElement method returns a successive element of the series. In the latest version of JDK, there are better ways to hold a sequence of elements that's why very often there is a need to convert older Enumeration into something developers are more familiar with like for example Stream.

2. The Enumeration interface

The Enumeration interface is simple, it contains two methods:

  • hasMoreElements() - checks if this enumeration contains more elements,
  • nextElement() - returns the next element of this enumeration if this enumeration object has at least one more element to provide.

To print all elements from Enumeration we could use for statement like in the following example:

for (Enumeration<E> e = v.elements(); e.hasMoreElements();) {
     System.out.println(e.nextElement());
}

3. Convert Enumeration to Stream using Spliterators and Iterator interface

Since Spliterators using the newest Iterator interface which is very similar to Enumeration it seems like a good idea to use it for the conversion.

In the following example we created a helper method enumerationAsStream that converts Enumeration to Stream using that approach:

package com.frontbackend.java;

import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public class EnumerationToStreamUsingSpliterator {

    public static void main(String[] args) {
        Enumeration<String> enumeration = Collections.enumeration(Arrays.asList("one", "two", "three"));

        Stream<String> stream = enumerationAsStream(enumeration); // convert Enumeration to Stream

        stream.forEach(System.out::println); // print elements from Stream
    }

    public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator<T>() {
            @Override
            public T next() {
                return e.nextElement();
            }

            @Override
            public boolean hasNext() {
                return e.hasMoreElements();
            }

            public void forEachRemaining(Consumer<? super T> action) {
                while (e.hasMoreElements())
                    action.accept(e.nextElement());
            }
        }, Spliterator.ORDERED), false);
    }
}

We created anonymous class that overrides three Iterator methods: next(), hasNext() and forEachRemaining().

In this approache, we don't have to know the exact number of elements hold in the Enumeration object.

4. Convert Enumeration to Stream using Guava

We could use external libraries such as Guava to convert Enumeration into Iterator and use it in Spliterators. This is the same approach as in point 2 but here we could get rid of many lines of code:

package com.frontbackend.java;

import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import com.google.common.collect.Iterators;

public class EnumerationToStreamUsingIterators {

    public static void main(String[] args) {
        Enumeration<String> enumeration = Collections.enumeration(Arrays.asList("one", "two", "three"));

        Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(Iterators.forEnumeration(enumeration), Spliterator.ORDERED);

        Stream<String> stream = StreamSupport.stream(spliterator, false);

        stream.forEach(System.out::println); // print elements from Stream
    }
}

In this example, we make use of Guava's Iterators.forEnumeration(...) utility method.

5. Convert Enumeration to Stream using Apache Common library

Another library we could use to convert Enumeration into Iterator and then use it to create a Stream out of it is Apache Common:

package com.frontbackend.java;

import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.apache.commons.collections4.IteratorUtils;

public class EnumerationToStreamUsingIteratorUtils {

    public static void main(String[] args) {
        Enumeration<String> enumeration = Collections.enumeration(Arrays.asList("one", "two", "three"));

        Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(IteratorUtils.asIterator(enumeration), Spliterator.ORDERED);

        Stream<String> stream = StreamSupport.stream(spliterator, false);

        stream.forEach(System.out::println); // print elements from Stream
    }
}

In this approache, we make use of Apache Commons IteratorUtils.asIterator(...) helper method.

6. Java 9 solution

In Java 9 there is a possible way to convert an Enumeration into Stream using a one-liner solution:

Enumeration<String> enumeration = Collections.enumeration(Arrays.asList("one", "two", "three"));

Stream<String> stream = StreamSupport.stream(
    Spliterators.spliteratorUnknownSize(enumeration.asIterator(), Spliterator.ORDERED),
    false
);

In Java 9 new method was introduced to the Enumeration interface:

  • default Iterator<E> asIterator() - this method returns an Iterator that traverses the remaining elements covered by this enumeration.

There is also a way to convert Enumeration to Stream by converting Iterator to Collection first, but in that approach, we will have to copy all elements, which could be very resource-consuming.

7. Conclusion

In this article, we presented how to convert an Enumeration into a Stream object.

As always, the source code used in this tutorial can be found on GitHub.

{{ message }}

{{ 'Comments are closed.' | trans }}