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>();
Stream<String> targetStream =;

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

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

Exception in thread "main" java.util.NoSuchElementException
    at java.util.AbstractList$
    at Main$$Lambda$1/1175962212.get(Unknown Source)
    at java.util.Spliterator.forEachRemaining(
    at Main.main(

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

9 s

One way is to create a Spliterator from the Iterator and use that as a basis for your stream:

Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream =
          Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),

An alternative which is maybe more readable is to use an Iterable – and creating an Iterable from an Iterator is very easy with lambdas because Iterable is a functional interface:

Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();

Iterable<String> iterable = () -> sourceIterator;
Stream<String> targetStream =, false);

Leave a Comment