私にを提供するサードパーティのライブラリがありEnumeration<String>
ます。私はその列挙をJava 8としてゆっくりと処理し、などをStream
呼び出したいと思います。filter
map
flatMap
これが含まれている既存のライブラリはありますか?私はすでにGuavaとApache Commonsを参照しているので、これらのいずれかが理想的なソリューションを備えているかどうか。
または、すべての怠惰な性質を保持しながらEnumeration
、a Stream
をa に変える最善/最も簡単な方法は何ですか?
この答えは、すでに作成ソリューション提供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);
}
ソースコードレベルでは、この実装はにIterator
基づくのと同じくらい簡単ですが、a Spliterator
からへの委任を排除しIterator
ます。読者が新しいAPIについて学ぶ必要があるだけです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加