我有一个第三方图书馆给我一个图书馆Enumeration<String>。我想像Java 8那样懒惰地使用该枚举,并Stream调用诸如此类的东西。filter``map``flatMap
Enumeration<String>
Stream
filter``map``flatMap
有没有现成的图书馆?我已经在引用Guava和Apache Commons,所以如果其中任何一个都有理想的解决方案。
另外,在保留所有内容的懒惰性质的同时将Enumerationa 变成最佳/最简单的方法Stream是什么?
Enumeration
这个答案已经提供了一个解决方案,可以解决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对于大多数非短路操作,实现将调用所述方法:
forEachRemaining
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直接实现相比,没有任何优势:
Iterator
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); }
在源代码级别上,此实现与Iterator基于- 一样简单,但是消除了从Spliterator到的委派Iterator。它仅要求其读者学习新的API。