The Stream.of
method, used to create a stream from otherwise un-associated values, returns an sequential, ordered stream.
Returns a sequential ordered stream whose elements are the specified values.
According to the package Javadocs for java.util.stream
, Side Effects section:
IntStream.range(0,5).parallel().map(x -> x*2).toArray()
must produce [0, 2, 4, 6, 8]
This implies that parallel()
and map()
preserve whether the stream is sequential/ordered.
I've traced the implementation of the Stream
that Stream.of
creates to a class called ReferencePipeline
.
@Override
public final Iterator<P_OUT> iterator() {
return Spliterators.iterator(spliterator());
}
That implementation's iterator()
method defers to Spliterator.iterator()
, whose code adapts to the Iterator
interface by simply relying on the Spliterator
's tryAdvance
method, and does not change any stream characteristics:
public static<T> Iterator<T> iterator(Spliterator<? extends T>
spliterator) {
Objects.requireNonNull(spliterator);
class Adapter implements Iterator<T>, Consumer<T> {
boolean valueReady = false;
T nextElement;
@Override
public void accept(T t) {
valueReady = true;
nextElement = t;
}
@Override
public boolean hasNext() {
if (!valueReady)
spliterator.tryAdvance(this);
return valueReady;
}
@Override
public T next() {
if (!valueReady && !hasNext())
throw new NoSuchElementException();
else {
valueReady = false;
return nextElement;
}
}
}
return new Adapter();
}
In conclusion, yes, the order is guaranteed because Stream.of
creates a "sequential ordered stream", and none of the operations you use above: parallel
, map
, or iterator
change the characteristics. In fact, iterator
uses the underlying Stream Spliterator
to iterate over the stream elements.