Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in Java by (10.2k points)

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 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.

1 Answer

0 votes
by (46k points)

One method is to make 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 = StreamSupport.stream(

          Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),

          false);

An option which is maybe more readable is to try an Iterable - and making 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 = StreamSupport.stream(iterable.spliterator(), false);

Related questions

0 votes
1 answer
0 votes
1 answer
0 votes
1 answer
0 votes
1 answer

31k questions

32.8k answers

501 comments

693 users

Browse Categories

...