1. Overview
1.概述
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.
枚举是Java第一个版本(JDK 1.0)的一个接口。这个接口是通用的,提供了对元素序列的懒散访问。尽管在新版本的Java中有更好的替代方案,但传统的实现仍然可以使用Enumeration接口返回结果。 因此,为了使传统实现现代化,开发人员可能必须将Enumeration对象转换为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.
在这个简短的教程中,我们将实现一个将Enumeration对象转换为Java Stream API的实用方法。因此,我们将能够使用诸如filter和map等流方法。
2. Java’s Enumeration Interface
2.Java的枚举接口
Let’s start with an example to illustrate the use of an Enumeration object:
让我们从一个例子开始,说明Enumeration对象的使用。
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.
枚举有两个主要方法。hasMoreElements和nextElement。我们应该同时使用这两个方法来迭代元素的集合。
3. Creating a Spliterator
3.创建一个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:
作为第一步,我们将为AbstractSpliterator抽象类创建一个具体类。这个类对于将Enumeration对象调整到Spliterator接口是必要的。
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.
除了创建类,我们还需要创建一个构造函数。我们应该向super构造函数传递前两个参数。第一个参数是Spliterator的估计大小。第二个是用于定义额外的特性。最后,我们要用最后一个参数来接收Enumeration对象。
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:
我们还需要覆盖tryAdvance和forEachRemaining方法。它们将被Stream API用来对Enumeration的元素执行操作。
@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
4.将枚举转换为流
Now, using the EnumerationSpliterator class, we’re able to use the StreamSupport API for performing the conversion:
现在,使用EnumerationSpliterator类,我们就可以使用StreamSupport API来执行转换。
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.
在这个实现中,我们需要创建一个EnumerationSpliterator类的实例。Long.MAX_VALUE是估计大小的默认值。Spliterator.ORDERED定义了流将按照枚举提供的顺序来迭代元素。
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.
接下来,我们应该调用stream类中的StreamSupport方法。我们需要传递EnumerationSpliterator实例作为第一个参数。最后一个参数是定义流是并行的还是顺序的。
5. Testing Our Implementation
5.测试我们的实施
By testing our convert method, we can observe that now we’re able to create a valid Stream object based on an Enumeration:
通过测试我们的convert方法,我们可以观察到,现在我们能够基于Enumeration创建一个有效的Stream对象。
@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
6.结论
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.
在本教程中,我们展示了如何将Enumeration转换成Stream对象。像往常一样,源代码可以在GitHub上找到over。