如何将 Java 枚举转换为流?
我有一个第三方库,它给了我一个.我想像 Java 8 一样懒惰地使用这个枚举,调用类似 的东西,并在它上面。Enumeration<String>
Stream
filter
map
flatMap
是否有现有的库中包含此内容?我已经引用了Guava和Apache Commons,所以如果其中任何一个有解决方案,那将是理想的。
或者,将一个同时保持一切的懒惰本质的最好/最简单的方法是什么?Enumeration
Stream
我有一个第三方库,它给了我一个.我想像 Java 8 一样懒惰地使用这个枚举,调用类似 的东西,并在它上面。Enumeration<String>
Stream
filter
map
flatMap
是否有现有的库中包含此内容?我已经引用了Guava和Apache Commons,所以如果其中任何一个有解决方案,那将是理想的。
或者,将一个同时保持一切的懒惰本质的最好/最简单的方法是什么?Enumeration
Stream
为什么不使用vanilla Java:
Collections.list(enumeration).stream()...
但是,正如@MicahZoltu中提到的,必须考虑枚举中的项数,因为首先将循环访问枚举以复制 .从那里可以使用常规方法。虽然这对于许多收集流操作是常见的,但如果枚举太大(如无限),这可能会导致问题,因为枚举必须在列表中进行转换,那么应该使用此处描述的其他方法。Collections.list
ArrayList
stream
这个答案已经提供了一个解决方案,该解决方案可以创建一个:Stream
Enumeration
public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) { return StreamSupport.stream( Spliterators.spliteratorUnknownSize( new Iterator<T>() { public T next() { return e.nextElement(); } public boolean hasNext() { return e.hasMoreElements(); } }, Spliterator.ORDERED), false); }
应该强调的是,结果与其他任何结果一样懒惰,因为它在终端操作开始之前不会处理任何项目,如果终端操作短路,它将仅迭代所需数量的项目。Stream
Stream
尽管如此,它仍有改进的余地。当有一种直接的方法来处理所有元素时,我总是会添加一个方法。所述方法将由大多数非短路操作的实现调用:forEachRemaining
Stream
public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
new Iterator<T>() {
public T next() {
return e.nextElement();
}
public boolean hasNext() {
return e.hasMoreElements();
}
public void forEachRemaining(Consumer<? super T> action) {
while(e.hasMoreElements()) action.accept(e.nextElement());
}
},
Spliterator.ORDERED), false);
}
但是,上面的代码是“使用,因为它是如此熟悉”的反模式的受害者。创建的将被包装到新接口的实现中,并且与直接实现相比没有任何优势:Iterator
Iterator
Spliterator
Spliterator
public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
return StreamSupport.stream(
new Spliterators.AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED) {
public boolean tryAdvance(Consumer<? super T> action) {
if(e.hasMoreElements()) {
action.accept(e.nextElement());
return true;
}
return false;
}
public void forEachRemaining(Consumer<? super T> action) {
while(e.hasMoreElements()) action.accept(e.nextElement());
}
}, false);
}
在源代码级别,此实现与基于 -一样简单,但消除了从 a 到 .它只需要读者了解新的API。Iterator
Spliterator
Iterator