Warm-up

Make the pipeline actually run

10 minjunior18 yrs

One concept, guided. Near-impossible to fail.

What this teaches

  • Intermediate operations build a pipeline and touch nothing
  • Only a terminal operation traverses the source
  • A chain with no terminal operation fails silently and looks like working code
  • A stream is consumed by its terminal operation and cannot be reused

Starter

Starter.java
import java.util.*;
import java.util.function.*;
import java.util.stream.*;

/**
 * Warm-up: the line that looks like working code and does nothing.
 *
 * Intermediate operations record what to do and return immediately. Nothing
 * reads the source until a terminal operation asks for a result. That single
 * fact explains most surprising stream behaviour.
 */
public class Starter {

    record Order(String id, boolean overdue) { }

    static final List<Order> ORDERS = List.of(
        new Order("A-1", true),
        new Order("A-2", false),
        new Order("A-3", true));

    static void sendReminder(Order order) {
        System.out.println("  reminder sent for " + order.id());
    }

    public static void main(String[] args) {
        // TODO 1: predict what this prints before running it.
        System.out.println("about to send reminders:");
        ORDERS.stream()
            .filter(Order::overdue)
            .map(order -> {
                sendReminder(order);
                return order.id();
            });
        System.out.println("done");

        // TODO 2: it printed nothing between the two lines. Say why, in terms
        // of intermediate and terminal operations — then say why no exception
        // and no warning appeared.

        // TODO 3: make it work. There are at least two correct terminal
        // operations here; pick the one that says the effect is the point.

        // TODO 4: build a pipeline into a variable without a terminal
        // operation, print a line, THEN call the terminal operation. Watch the
        // ordering of the output prove that nothing ran until you asked.

        // TODO 5: call a second terminal operation on that same variable.
        // Read the exception message out loud. Then fix it two ways — by
        // streaming the source again, and with a Supplier<Stream<Order>>.

        // TODO 6: list four terminal operations and four intermediate ones
        // from memory. The rule that tells them apart is the return type.
    }
}

Run it locally:

cd exercises/java/java8/stream-lazy-evaluation/01-warmup
javac Starter.java -d /tmp/out && java -cp /tmp/out Starter

Done when

  • You saw a chain of operations print nothing at all
  • You added a terminal operation and watched the same chain run
  • You triggered IllegalStateException by reusing a stream, and can say why
  • You can name four terminal operations without looking

← Back to Why does a stream with no terminal operation do nothing?