639 Stimmen

Wie konvertiert man einen Iterator in einen Stream?

Ich suche nach einer prägnanten Möglichkeit, einen Iterator in einen Stream umzuwandeln oder genauer gesagt, den Iterator als Stream zu "anzeigen".

Aus Leistungsgründen möchte ich eine Kopie des Iterators in einer neuen Liste vermeiden:

Iterator sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection copyList = new ArrayList();
sourceIterator.forEachRemaining(copyList::add);
Stream targetStream = copyList.stream();

Basierend auf einigen Vorschlägen in den Kommentaren habe ich auch versucht, Stream.generate zu verwenden:

public static void main(String[] args) throws Exception {
    Iterator sourceIterator = Arrays.asList("A", "B", "C").iterator();
    Stream targetStream = Stream.generate(sourceIterator::next);
    targetStream.forEach(System.out::println);
}

Ich erhalte jedoch eine NoSuchElementException (da keine Aufruf von hasNext stattfindet)

Exception in thread "main" java.util.NoSuchElementException
    at java.util.AbstractList$Itr.next(AbstractList.java:364)
    at Main$$Lambda$1/1175962212.get(Unknown Source)
    at java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef.tryAdvance(StreamSpliterators.java:1351)
    at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at Main.main(Main.java:20)

Ich habe mir StreamSupport und Collections angesehen, aber nichts gefunden.

11voto

Bassem Reda Zohdy Punkte 12387

Erstellen Sie einen Spliterator aus einem Iterator unter Verwendung der Spliterators-Klasse, die mehr als eine Funktion zum Erstellen eines Spliterators enthält. Zum Beispiel verwende ich hier spliteratorUnknownSize, der den Iterator als Parameter erhält, und erstelle dann einen Stream unter Verwendung von StreamSupport.

Spliterator spliterator = Spliterators.spliteratorUnknownSize(
        iterator, Spliterator.NONNULL);
Stream stream = StreamSupport.stream(spliterator, false);

3voto

Stream.iterate erledigt die Arbeit für Sie. Iterieren Sie einfach, solange es Elemente gibt, und ordnen Sie sie dem nächsten Element zu.

public  Stream toStream(Iterator iter) {
    return Stream.iterate(iter, Iterator::hasNext, UnaryOperator.identity()).map(Iterator::next);
}

2voto

Marinos An Punkte 7473

1 Lösung von assylias in einer Methode verpackt:

public static  Stream toStream(Iterator iterator) {
    return StreamSupport.stream(((Iterable)() -> iterator).spliterator(), false);
}

2 guava Streams Implementierung (gekennzeichnet mit @Beta):

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

2voto

Robert Niestroj Punkte 14014

Wenn Sie Spring (Data) verwenden, gibt es eine Hilfsklasse StreamUtils, die zwei Methoden hat:

createStreamFromIterator(Iterator iterator) 

createStreamFromIterator(CloseableIterator iterator)

https://docs.spring.io/spring-data/commons/docs/3.0.0/api/org/springframework/data/util/StreamUtils.html#createStreamFromIterator(java.util.Iterator)

0voto

Chavi Punkte 1

Wenn die Iterationsgröße bekannt ist, ist dies möglich:

public static void main(String[] args) throws Exception {
    Iterator sourceIterator = Arrays.asList("A", "B", "C").iterator();
    Stream targetStream = Stream.generate(sourceIterator::next);
    targetStream.**limit(3)**.forEach(System.out::println);
}

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