Diese Antwort bietet bereits eine Lösung, die Streamaus einem 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);
}
Es sollte betont werden , dass die resultierende Stream ist wie jede andere als faul Stream, da es keine Produkte verarbeiten , bevor das Terminal Aktion begonnen wurde , und wenn die Terminalbetrieb Kurzschluss ist, wird es nur so viele Punkte wie nötig wiederholen.
Dennoch gibt es Raum für Verbesserungen. Ich würde immer eine forEachRemainingMethode hinzufügen , wenn es eine einfache Möglichkeit gibt, alle Elemente zu verarbeiten. Diese Methode wird von der StreamImplementierung für die meisten nicht kurzgeschlossenen Operationen aufgerufen :
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);
}
Der obige Code ist jedoch ein Opfer des IteratorAntipatterns "Verwenden, weil es so vertraut ist". Das erstellte Iteratorwird in eine Implementierung der neuen SpliteratorSchnittstelle eingebunden und bietet keinen Vorteil gegenüber der Spliteratordirekten Implementierung :
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);
}
Auf der Quellcode-Ebene ist diese Implementierung so einfach wie die Iterator-basierte, eliminiert jedoch die Delegierung von a Spliteratornach a Iterator. Die Leser müssen lediglich die neue API kennenlernen.