Stream and lazy evaluation

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)


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.

The time when terminal operation is called, traversal of streams begins and the associated function is performed one by one.

Parallel streams don't evaluate streams 'one by one' (at terminal point). The operations are rather performed simultaneously, depending on the available cores.