HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavaCritical

How to convert an Iterator to a Stream?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
streamconvertiteratorhow

Problem

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 sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection copyList = new ArrayList();
sourceIterator.forEachRemaining(copyList::add);
Stream 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 sourceIterator = Arrays.asList("A", "B", "C").iterator();
    Stream 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.

Solution

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

Iterator sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream targetStream = StreamSupport.stream(
          Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),
          false);


A potentially more readable alternative is to use an Iterable - and creating an Iterable from an Iterator is very easy with lambdas because Iterable is a functional interface:

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

Iterable iterable = () -> sourceIterator;
Stream targetStream = StreamSupport.stream(iterable.spliterator(), false);

Code Snippets

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

Iterable<String> iterable = () -> sourceIterator;
Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);

Context

Stack Overflow Q#24511052, score: 731

Revisions (0)

No revisions yet.