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.
In Java 8, we can use Stream. iterate to create stream values on demand, so called infinite stream.
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.
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.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With