[java] How to convert an iterator to a stream?

I am looking for a concise way to convert an Iterator to a Stream or more specifically to "view" the iterator as a stream.

For performance reason, I would like to avoid a copy of the iterator in a new list:

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

Based on the some suggestions in the comments, I have also tried to use Stream.generate:

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

However, I get a NoSuchElementException (since there is no invocation of hasNext)

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)

I have looked at StreamSupport and Collections but I didn't find anything.

This question is related to java iterator java-8

The answer is


This is possible in Java 9.

Stream.generate(() -> null)
    .takeWhile(x -> iterator.hasNext())
    .map(n -> iterator.next())
    .forEach(System.out::println);

Use Collections.list(iterator).stream()...


import com.google.common.collect.Streams;

and use Streams.stream(iterator) :

Streams.stream(iterator)
       .map(v-> function(v))
       .collect(Collectors.toList());

Great suggestion! Here's my reusable take on it:

public class StreamUtils {

    public static <T> Stream<T> asStream(Iterator<T> sourceIterator) {
        return asStream(sourceIterator, false);
    }

    public static <T> Stream<T> asStream(Iterator<T> sourceIterator, boolean parallel) {
        Iterable<T> iterable = () -> sourceIterator;
        return StreamSupport.stream(iterable.spliterator(), parallel);
    }
}

And usage (make sure to statically import asStream):

List<String> aPrefixedStrings = asStream(sourceIterator)
                .filter(t -> t.startsWith("A"))
                .collect(toList());

Create Spliterator from Iterator using Spliterators class contains more than one function for creating spliterator, for example here am using spliteratorUnknownSize which is getting iterator as parameter, then create Stream using StreamSupport

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

Since version 21, Guava library provides Streams.stream(iterator)

It does what @assylias's answer shows.


Another way to do this on Java 9+ using Stream::iterate(T, Predicate, UnaryOperator):

Stream.iterate(iterator, Iterator::hasNext, UnaryOperator.identity())
        .map(Iterator::next)
        .forEach(System.out::println);

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to iterator

Iterating over Typescript Map Update row values where certain condition is met in pandas How to iterate (keys, values) in JavaScript? How to convert an iterator to a stream? How to iterate through a list of objects in C++ How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it? How to read one single line of csv data in Python? 'numpy.float64' object is not iterable Python list iterator behavior and next(iterator) python JSON only get keys in first level

Examples related to java-8

Default interface methods are only supported starting with Android N Class has been compiled by a more recent version of the Java Environment Why is ZoneOffset.UTC != ZoneId.of("UTC")? Modify property value of the objects in list using Java 8 streams How to use if-else logic in Java 8 stream forEach Android Studio Error: Error:CreateProcess error=216, This version of %1 is not compatible with the version of Windows you're running Error:could not create the Java Virtual Machine Error:A fatal exception has occured.Program will exit What are functional interfaces used for in Java 8? java.time.format.DateTimeParseException: Text could not be parsed at index 21 Java 8 lambda get and remove element from list