Konvertiere Iterable in Stream mit Java 8 JDK

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

Ich möchte dieses Ergebnis mit der Java 8 Stream API manipulieren.

Jedoch kann Iterable nicht “streamen”.

Gibt es eine bessere Idee, wie Streams zu verwenden sind (ohne Iterable in List zu konvertieren)?

Solutions Collecting From Web of "Konvertiere Iterable in Stream mit Java 8 JDK"

Es gibt eine viel bessere Antwort als die spliteratorUnknownSize Verwendung von spliteratorUnknownSize , was sowohl einfacher ist als auch ein besseres Ergebnis spliteratorUnknownSize . Iterable hat eine spliterator() -Methode, also sollten Sie diese verwenden, um Ihren Spliterator zu erhalten. Im schlimmsten Fall ist es derselbe Code (die Standardimplementierung verwendet spliteratorUnknownSize ), aber im allgemeineren Fall, wo Ihr Iterable bereits eine Sammlung ist, erhalten Sie einen besseren Spliterator und somit eine bessere Stream-performance (vielleicht sogar gute Parallelität) .) Es ist auch weniger Code:

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

Wie Sie sehen können, ist das Abrufen eines Streams von einem Iterable (siehe Warum bietet Iterable keine Stream () – und ParallelStream () -Methoden? ) Nicht sehr schmerzhaft.

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

 Streams.stream(iterable) 

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 ); } 

Ich würde vorschlagen, die JOOL- Bibliothek zu verwenden, sie verbirgt die Magie des Spliterators hinter dem Seq.seq-Aufruf (iterable) und bietet eine ganze Reihe zusätzlicher nützlicher functionen.

Ich habe diese class erstellt:

 public class Streams { /** * Converts Iterable to stream */ public static  Stream streamOf(final Iterable iterable) { return toStream(iterable, false); } /** * Converts Iterable to parallel stream */ public static  Stream parallelStreamOf(final Iterable iterable) { return toStream(iterable, true); } private static  Stream toStream(final Iterable iterable, final boolean isParallel) { return StreamSupport.stream(iterable.spliterator(), isParallel); } } 

Ich denke, es ist perfekt lesbar, weil Sie nicht über Spliteratoren und Booleans (isParallel) nachdenken müssen.

Eine sehr einfache Streamable für dieses Problem besteht darin, eine Streamable -Schnittstelle zu erstellen, die Streamable erweitert, die eine default stream() -Methode enthält.

 interface Streamable extends Iterable { default Stream stream() { return StreamSupport.stream(spliterator(), false); } } 

Nun kann jedes deiner Iterable s einfach streambar gemacht werden, indem man sie als implements Streamable anstelle von Iterable .

Als eine andere Antwort erwähnt Guava Unterstützung dafür mit:

 Streams.stream(iterable); 

Ich möchte hervorheben, dass die Implementierung etwas anders ist als andere vorgeschlagene Antworten. Wenn das Iterable vom Typ Collection es geworfen.

 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 ); } 

Wenn Sie Vavr (früher bekannt als Javaslang) verwenden, kann dies so einfach sein wie:

 Iterable i = //... Stream.ofAll(i);