528 Stimmen

Konvertiere Iterable in Stream mit Java 8 JDK

Ich habe eine Schnittstelle, die java.lang.Iterable zurückgibt.

Ich würde gerne dieses Ergebnis mit der Java 8 Stream-API manipulieren.

Iterable kann jedoch nicht "streamen".

Irgendwelche Ideen, wie man das Iterable als Stream verwenden kann, ohne es in eine Liste umzuwandeln?

717voto

Brian Goetz Punkte 83148

Iterable hat eine Methode spliterator(), die Sie an StreamSupport.stream übergeben können, um einen Stream zu erstellen:

StreamSupport.stream(iterable.spliterator(), false)
             .filter(...)
             .moreStreamOps(...);

Dies ist eine viel bessere Antwort als die direkte Verwendung von spliteratorUnknownSize , da es sowohl einfacher ist als auch ein besseres Ergebnis liefert. Im schlimmsten Fall handelt es sich um denselben Code (die Standardimplementierung verwendet spliteratorUnknownSize), aber im häufigeren Fall, wo Ihr Iterable bereits eine Sammlung ist, erhalten Sie einen besseren Spliterator und somit eine bessere Stream-Leistung (vielleicht sogar eine gute Parallelität). Außerdem ist es weniger Code.

Wie Sie sehen können, ist das Erhalten eines Streams aus einem Iterable (siehe auch diese Frage) nicht sehr schmerzhaft.

99voto

numéro6 Punkte 3592

Wenn Sie die Guava-Bibliothek verwenden können, können Sie seit Version 21 verwenden

Streams.stream(iterable)

24voto

nosid Punkte 47014

Sie können einfach einen Stream aus einem Iterable oder Iterator erstellen:

public static  Stream stream(Iterable iterable) {
    return StreamSupport.stream(
        Spliterators.spliteratorUnknownSize(
            iterable.iterator(),
            Spliterator.ORDERED
        ),
        false
    );
}

11voto

Shaggie Punkte 14164

Ich würde vorschlagen, die Verwendung der JOOL Bibliothek, sie verbirgt die Spliterator-Magie hinter dem Seq.seq(iterable) Aufruf und bietet zudem eine Vielzahl zusätzlicher nützlicher Funktionen.

9voto

Alexander Oh Punkte 22027

Wie in einer anderen Antwort erwähnt, unterstützt Guava dies durch:

Streams.stream(iterable);

Ich möchte darauf hinweisen, dass die Implementierung etwas anders ist als von anderen Antworten vorgeschlagen. Wenn das Iterable vom Typ Collection ist, wird es gecastet.

public static  Stream stream(Iterable iterable) {
  return (iterable instanceof Collection)
    ? ((Collection) iterable).stream()
    : StreamSupport.stream(iterable.spliterator(), false);
}

public static  Stream stream(Iterator iterator) {
  return StreamSupport.stream(
    Spliterators.spliteratorUnknownSize(iterator, 0),
    false
  );
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X