This is a example: code A:
files.forEach(f -> {
//TODO
});
and another code B may use on this way:
files.stream().forEach(f -> { });
What is the difference between both, with stream()
and no stream()
?
This is a example: code A:
files.forEach(f -> {
//TODO
});
and another code B may use on this way:
files.stream().forEach(f -> { });
What is the difference between both, with stream()
and no stream()
?
Practically speaking, they are mostly the same, but there is a small semantic difference.
Code A is defined by Iterable.forEach
, whereas code B is defined by Stream.forEach
. The definition of Stream.forEach
allows for the elements to be processed in any order -- even for sequential streams. (For parallel streams, Stream.forEach
will very likely process elements out-of-order.)
Iterable.forEach
gets an Iterator from the source and calls forEachRemaining()
on it. As far as I can see, all current (JDK 8) implementations of Stream.forEach
on the collections classes will create a Spliterator built from one of the source's Iterators, and will then call forEachRemaining
on that Iterator -- just like Iterable.forEach
does. So they do the same thing, though the streams version has some extra setup overhead.
However, in the future, it's possible that the streams implementation could change so that this is no longer the case.
(If you want to guarantee ordering of processing streams elements, use forEachOrdered()
instead.)
There is no difference in terms of semantics, though the direct implementation without stream
is probably slightly more efficient.
A stream is an sequence of elements (i.e a data structure) for using up an operation or iteration. Any Collection can be exposed as a stream. The operations you perform on a stream can either be
Intermediate operations (map, skip, concat, substream, distinct, filter, sorted, limit, peek..) producing another java.util.stream.Stream but the intermediate operations are lazy operations, which will be executed only after a terminal operation was executed.
And the Terminal operations (forEach, max, count, matchAny, findFirst, reduce, collect, sum, findAny ) producing an object that is not a stream.
Basically it is similar to pipeline as in Unix.
Both approaches uses the terminal operation Iterable.forEach
, but the version with .stream()
also unnecessarily creates a Stream
object representing the List. While there is no difference, it is suboptimal.