I'm reading from the java 8 API on the stream abstraction but I don't understand this sentence very well:
Intermediate operations return a new stream. They are always lazy; executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream that, when traversed, contains the elements of the initial stream that match the given predicate. Traversal of the pipeline source does not begin until the terminal operation of the pipeline is executed.
When a filter operation creates a new stream does that stream contain a filtered element? It seems to understand that the stream contains elements only when it is traversed i.e with a terminal operation. But, then, what does the filtered stream contain? I'm confused!!!
Streams are lazy because intermediate operations are not evaluated unless terminal operation is invoked. Each intermediate operation creates a new stream, stores the provided operation/function and return the new stream. The pipeline accumulates these newly created streams.
Lazy evaluation is an evaluation strategy which delays the evaluation of an expression until its value is needed. The opposite of this is eager evaluation, where an expression is evaluated as soon as it is bound to a variable.[wikipedia]
Functional languages like Haskell are lazy evaluated, but not OCaml, which is eagerly evaluated.
It means that the filter is only applied during the terminal operation. Think of something like this:
public Stream filter(Predicate p) { this.filter = p; // just store it, don't apply it yet return this; // in reality: return a new stream } public List collect() { for (Object o : stream) { if (filter.test(o)) list.add(o); } return list; }
(That does not compile and is a simplification of the reality but the principle is there)
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