Ist es möglich, eine Enumeration
mit Lambda-Ausdruck zu iterieren ? Was ist die Lambda-Darstellung des folgenden Code-Snippets:
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
while (nets.hasMoreElements()) {
NetworkInterface networkInterface = nets.nextElement();
}
Ich habe keinen Stream darin gefunden.
Antworten:
Falls Ihnen die Tatsache nicht gefällt, dass
Collections.list(Enumeration)
der gesamte Inhalt vor Beginn der Iteration in eine (temporäre) Liste kopiert wird, können Sie sich mit einer einfachen Dienstprogrammmethode helfen:public static <T> void forEachRemaining(Enumeration<T> e, Consumer<? super T> c) { while(e.hasMoreElements()) c.accept(e.nextElement()); }
Dann können Sie einfach
forEachRemaining(enumeration, lambda-expression);
(beachten Sie dieimport static
Funktion) ...quelle
(Diese Antwort zeigt einen von vielen Optionen Nur weil ist.
HatZeichen für die Annahme hat, bedeutet nicht , es ist die beste, die ich andere Antworten empfehlen zu lesen und Kommissionierung je nach Situation Sie sind in IMO:..- für Java 8 Holger Antwort schönsten ist, denn abgesehen von einfach ist es nicht zusätzliche Iteration benötigt , die in meiner Lösung geschieht.
- für Java 9 würde ich Lösung von Pick Tagir Valeev Antwort )
Sie können Elemente von Ihrem
Enumeration
nachArrayList
mit kopierenCollections.list
und dann wie folgt verwendenquelle
Enum
aber die Frage ist ungefährEnumeration
.Wenn Ihr Code viele Aufzählungen enthält, empfehle ich, eine statische Hilfsmethode zu erstellen, die eine Aufzählung in einen Stream konvertiert . Die statische Methode könnte wie folgt aussehen:
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); }
Verwenden Sie die Methode mit einem statischen Import . Im Gegensatz zur Lösung von Holger können Sie von den verschiedenen Stream- Vorgängen profitieren , wodurch der vorhandene Code möglicherweise noch einfacher wird. Hier ist ein Beispiel:
quelle
list.forEach(…)
undlist.stream(). ⟨stream ops⟩ .forEach(…)
.public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) { return Collections.list(e).stream(); }
würde das gleiche tun, aber viel einfacher.Seit Java-9 wird es eine neue Standardmethode geben,
Enumeration.asIterator()
die die reine Java-Lösung vereinfacht:quelle
Sie können die folgende Kombination von Standardfunktionen verwenden:
Sie können auch weitere Merkmale wie
NONNULL
oder hinzufügenDISTINCT
.Nach dem Anwenden statischer Importe wird dies besser lesbar:
stream(spliteratorUnknownSize(toIterator(enumeration), IMMUTABLE), false)
Jetzt haben Sie einen Standard-Java 8-Stream, der auf jede Weise verwendet werden kann! Sie können
true
für die parallele Verarbeitung übergeben.Verwenden Sie eine der folgenden Optionen, um von Enumeration zu Iterator zu konvertieren:
CollectionUtils.toIterator()
ab Spring 3.2 oder Sie können verwendenIteratorUtils.asIterator()
aus Apache Commons-Sammlungen 3.2Iterators.forEnumeration()
von Google Guavaquelle
org.apache.commons.collections.CollectionUtils
.Für Java 8 ist die einfachste Umwandlung der Aufzählung in Stream:
Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
quelle
Ich weiß, dass dies eine alte Frage ist, aber ich wollte eine Alternative zu den Funktionen Collections.asList und Stream vorstellen. Da die Frage den Titel "Iteration an Enumeration" trägt, wird manchmal ein Lambda-Ausdruck verwendet, aber eine erweiterte for-Schleife ist möglicherweise vorzuziehen, da das aufgezählte Objekt möglicherweise eine Ausnahme auslöst und die for-Schleife in einem größeren Versuch einfacher zu kapseln ist. Fangcodesegment (Lambdas erfordern deklarierte Ausnahmen, um innerhalb des Lambda gefangen zu werden). Zu diesem Zweck wird hier ein Lambda verwendet, um eine Iterable zu erstellen, die in einer for-Schleife verwendet werden kann und die Aufzählung nicht vorlädt:
/** * Creates lazy Iterable for Enumeration * * @param <T> Class being iterated * @param e Enumeration as base for Iterator * @return Iterable wrapping Enumeration */ public static <T> Iterable<T> enumerationIterable(Enumeration<T> e) { return () -> new Iterator<T>() { @Override public T next() { return e.nextElement(); } @Override public boolean hasNext() { return e.hasMoreElements(); } }; }
quelle