This post will discuss how to create a sequential stream from an iterator in Java.

A sequential stream is a stream that processes elements one by one in a single thread. An iterator is an object that allows traversing through a collection of elements. Here are some of the methods to create a sequential stream from an iterator:

1. Using a Spliterator

Creating a sequential stream from an iterator is a two-step process in Java. The first step involves converting the iterator into a spliterator, and in the second step, we turn that spliterator into a Stream. A spliterator can split a source of elements into smaller parts and traverse them. To create a spliterator from an iterator, we can use the Spliterators.spliteratorUnknownSize() method, which takes an iterator and some characteristics as parameters. Then, we can call the StreamSupport.stream() method to create a new sequential or parallel stream. It takes a spliterator and a boolean flag indicating whether the stream is parallel or not, and returns a stream. Here’s an example of this approach:

Download  Run Code

2. Using an Iterable

The Iterable interface provides a spliterator() method that creates a spliterator over the elements described by the iterable. Since Iterable interface declares a single abstract method iterator() that returns an Iterator<T>, this makes iterable effectively a FunctionalInterface and creating an iterable from an iterator can be done using a lambda expression that returns the iterator itself. To illustrate, consider the following example.

Download  Run Code

 
Please note that the Iterable.spliterator() method itself internally calls the Spliterators.spliteratorUnknownSize() method to get a spliterator over the elements described by the iterable.

3. Using Guava Library

Guava library introduced Streams class in version 21.0, which has a stream() method that returns a sequential stream of the remaining contents of the iterator. This method also internally calls the Spliterators.spliteratorUnknownSize() method to convert the iterator to a spliterator and StreamSupport.stream() to get a sequential stream from spliterator.

Download Code

4. Using Stream.generate() method

Another option is to use the Stream.generate() method with Iterator.next() method as the supplier. But this will only work with infinite streams and throw NoSuchElementException with finite Streams. This is because Iterator.hasNext() is never called to determine whether the iteration has more elements.

Download  Run Code

 
If we know the total number of elements in the stream in advance, we can also use this method with finite streams. This way we can limit the stream using the limit() method, as follows:

Download  Run Code

 
Please note that after getting a stream of the elements from an iterator, the stream should be consumed immediately. Since streams are lazy in Java, it is linked only to an iterator, but if the iterator is used before calling a terminal operation on the stream, the stream would be left with only remaining items.

That’s all about creating a sequential Stream from an iterator in Java.