Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 855
gontard Avatar asked Jul 01 '14 13:07

gontard


People also ask

Does stream use Iterator Java?

In Java 8, we can use Stream. iterate to create stream values on demand, so called infinite stream.

How do I turn an iterable into a list?

To convert iterable to Collection, the iterable is first converted into spliterator. Then with the help of StreamSupport. stream(), the spliterator can be traversed and then collected with the help collect() into collection.

What is the difference between Iterator and stream in Java?

Iterators, in Java, are used in Collection Framework to retrieve elements one by one. A stream in Java is a pipeline of objects from an array or a collection data source. A sequential stream is one in which the objects are pipelined in a single stream on the same processing system.

How do I iterate a stream?

Java Stream forEach() method is used to iterate over all the elements of the given Stream and to perform an Consumer action on each element of the Stream. The forEach() is a more concise way to write the for-each loop statements.


1 Answers

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 = StreamSupport.stream(           Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),           false); 

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 = StreamSupport.stream(iterable.spliterator(), false); 
like image 188
assylias Avatar answered Nov 10 '22 03:11

assylias