Your findUser(id) method might not find a user. Returning null leads to NullPointerException when callers forget to check. Optional makes the "might be absent" explicit - callers must handle both cases.

Create Optional values

Wrap values in Optional.

nullable
CreatingOptional.java
Replay: real traced execution (multi-file project)
// Creating and checking Optional values
// Concept: Optional - container for potentially absent value

import java.util.Optional;

public class CreatingOptional {
    public static void main(String[] args) {
        // Create Optional with value
        Optional<String> present = Optional.of("Hello");
        System.out.println("Present: " + present);

        // Create Optional from nullable value
        String nullable = "World";
        Optional<String> maybe1 = Optional.ofNullable(nullable);
        System.out.println("Maybe 1: " + maybe1);

        nullable = null;
        Optional<String> maybe2 = Optional.ofNullable(nullable);
        System.out.println("Maybe 2: " + maybe2);


        // Create empty Optional
        Optional<String> empty = Optional.empty();
        System.out.println("Empty: " + empty);

        // Check if value is present
        System.out.println("\nChecking presence:");
        System.out.println("present.isPresent(): " + present.isPresent());
        System.out.println("empty.isPresent(): " + empty.isPresent());

        // isEmpty (Java 11+)
        System.out.println("\npresent.isEmpty(): " + present.isEmpty());
        System.out.println("empty.isEmpty(): " + empty.isEmpty());

        // Get value if present
        if (present.isPresent()) {
            String value = present.get();
            System.out.println("\nValue: " + value);
        }

        if (empty.isPresent()) {
            System.out.println("This won't print");
        } else {
            System.out.println("Empty has no value");
        }

        // Example with numbers
        Optional<Integer> num1 = Optional.of(42);
        Optional<Integer> num2 = Optional.ofNullable(null);

        System.out.println("\nNumbers:");
        System.out.println("num1: " + num1);
        System.out.println("num2: " + num2);
        System.out.println("num1 present: " + num1.isPresent());
        System.out.println("num2 present: " + num2.isPresent());

    }
}
// Creating and checking Optional values
// Concept: Optional - container for potentially absent value

import java.util.Optional;

public class CreatingOptional {
    public static void main(String[] args) {
        // Create Optional with value
        Optional<String> present = Optional.of("Hello");
        System.out.println("Present: " + present);

        // Create Optional from nullable value
        String nullable = "Java";
        Optional<String> maybe1 = Optional.ofNullable(nullable);
        System.out.println("Maybe 1: " + maybe1);

        nullable = null;
        Optional<String> maybe2 = Optional.ofNullable(nullable);
        System.out.println("Maybe 2: " + maybe2);


        // Create empty Optional
        Optional<String> empty = Optional.empty();
        System.out.println("Empty: " + empty);

        // Check if value is present
        System.out.println("\nChecking presence:");
        System.out.println("present.isPresent(): " + present.isPresent());
        System.out.println("empty.isPresent(): " + empty.isPresent());

        // isEmpty (Java 11+)
        System.out.println("\npresent.isEmpty(): " + present.isEmpty());
        System.out.println("empty.isEmpty(): " + empty.isEmpty());

        // Get value if present
        if (present.isPresent()) {
            String value = present.get();
            System.out.println("\nValue: " + value);
        }

        if (empty.isPresent()) {
            System.out.println("This won't print");
        } else {
            System.out.println("Empty has no value");
        }

        // Example with numbers
        Optional<Integer> num1 = Optional.of(42);
        Optional<Integer> num2 = Optional.ofNullable(null);

        System.out.println("\nNumbers:");
        System.out.println("num1: " + num1);
        System.out.println("num2: " + num2);
        System.out.println("num1 present: " + num1.isPresent());
        System.out.println("num2 present: " + num2.isPresent());

    }
}
// Creating and checking Optional values
// Concept: Optional - container for potentially absent value

import java.util.Optional;

public class CreatingOptional {
    public static void main(String[] args) {
        // Create Optional with value
        Optional<String> present = Optional.of("Hello");
        System.out.println("Present: " + present);

        // Create Optional from nullable value
        String nullable = null;
        Optional<String> maybe1 = Optional.ofNullable(nullable);
        System.out.println("Maybe 1: " + maybe1);

        nullable = null;
        Optional<String> maybe2 = Optional.ofNullable(nullable);
        System.out.println("Maybe 2: " + maybe2);


        // Create empty Optional
        Optional<String> empty = Optional.empty();
        System.out.println("Empty: " + empty);

        // Check if value is present
        System.out.println("\nChecking presence:");
        System.out.println("present.isPresent(): " + present.isPresent());
        System.out.println("empty.isPresent(): " + empty.isPresent());

        // isEmpty (Java 11+)
        System.out.println("\npresent.isEmpty(): " + present.isEmpty());
        System.out.println("empty.isEmpty(): " + empty.isEmpty());

        // Get value if present
        if (present.isPresent()) {
            String value = present.get();
            System.out.println("\nValue: " + value);
        }

        if (empty.isPresent()) {
            System.out.println("This won't print");
        } else {
            System.out.println("Empty has no value");
        }

        // Example with numbers
        Optional<Integer> num1 = Optional.of(42);
        Optional<Integer> num2 = Optional.ofNullable(null);

        System.out.println("\nNumbers:");
        System.out.println("num1: " + num1);
        System.out.println("num2: " + num2);
        System.out.println("num1 present: " + num1.isPresent());
        System.out.println("num2 present: " + num2.isPresent());

    }
}
  1. present ← Optional[Hello], nullable ← World, maybe1 ← Optional[World]

    6public class CreatingOptional {7    public static void main(String[] args) {8        // Create Optional with value9        Optional<String> present→ Optional[Hello] = Optional.of("Hello");10        System.out.println("Present: " + presentOptional[Hello]);11        12        // Create Optional from nullable value13        String nullable→ World = "World";14        //@nullable="World", "Java", null15        Optional<String> maybe1→ Optional[World] = Optional.ofNullable(nullableWorld);16        System.out.println("Maybe 1: " + maybe1Optional[World]);17        18        nullable→ null = null;19        Optional<String> maybe2→ Optional.empty = Optional.ofNullable(nullablenull);20        System.out.println("Maybe 2: " + maybe2Optional.empty);21        22        //@help h123        // Optional.of(value) - throws if value is null24        // Optional.ofNullable(value) - creates empty if null25        // Optional.empty() - explicitly empty Optional26        //@end27        28        // Create empty Optional29        Optional<String> empty→ Optional.empty = Optional.empty();30        System.out.println("Empty: " + emptyOptional.empty);31        32        // Check if value is present33        System.out.println("\nChecking presence:");34        System.out.println("present.isPresent(): " + present.isPresent());35        System.out.println("empty.isPresent(): " + empty.isPresent());36        37        // isEmpty (Java 11+)38        System.out.println("\npresent.isEmpty(): " + present.isEmpty());39        System.out.println("empty.isEmpty(): " + empty.isEmpty());
    outputPresent: Optional[Hello]
    Maybe 1: Optional[World]
    Maybe 2: Optional.empty
    Empty: Optional.empty
    
    Checking presence:
    present.isPresent(): true
    empty.isPresent(): false
    
    present.isEmpty(): false
    empty.isEmpty(): true
  2. value ← Hello

    41// Get value if present42if (present.isPresent()) {43    String value→ Hello = present.get();44    System.out.println("\nValue: " + valueHello);45}
    output
    Value: Hello
  3. else

    48    System.out.println("This won't print");49} else {50    System.out.println("Empty has no value");51}
    outputEmpty has no value
  4. num1 ← Optional[42], num2 ← Optional.empty

    53// Example with numbers54Optional<Integer> num1→ Optional[42] = Optional.of(42);55Optional<Integer> num2→ Optional.empty = Optional.ofNullable(null);5657System.out.println("\nNumbers:");58System.out.println("num1: " + num1Optional[42]);59System.out.println("num2: " + num2Optional.empty);60System.out.println("num1 present: " + num1.isPresent());61System.out.println("num2 present: " + num2.isPresent());
    output
    Numbers:
    num1: Optional[42]
    num2: Optional.empty
    num1 present: true
    num2 present: false
  1. present ← Optional[Hello], nullable ← Java, maybe1 ← Optional[Java]

    6public class CreatingOptional {7    public static void main(String[] args) {8        // Create Optional with value9        Optional<String> present→ Optional[Hello] = Optional.of("Hello");10        System.out.println("Present: " + presentOptional[Hello]);11        12        // Create Optional from nullable value13        String nullable→ Java = "Java";14        Optional<String> maybe1→ Optional[Java] = Optional.ofNullable(nullableJava);15        System.out.println("Maybe 1: " + maybe1Optional[Java]);16        17        nullable→ null = null;18        Optional<String> maybe2→ Optional.empty = Optional.ofNullable(nullablenull);19        System.out.println("Maybe 2: " + maybe2Optional.empty);20        21        22        // Create empty Optional23        Optional<String> empty→ Optional.empty = Optional.empty();24        System.out.println("Empty: " + emptyOptional.empty);25        26        // Check if value is present27        System.out.println("\nChecking presence:");28        System.out.println("present.isPresent(): " + present.isPresent());29        System.out.println("empty.isPresent(): " + empty.isPresent());30        31        // isEmpty (Java 11+)32        System.out.println("\npresent.isEmpty(): " + present.isEmpty());33        System.out.println("empty.isEmpty(): " + empty.isEmpty());
    outputPresent: Optional[Hello]
    Maybe 1: Optional[Java]
    Maybe 2: Optional.empty
    Empty: Optional.empty
    
    Checking presence:
    present.isPresent(): true
    empty.isPresent(): false
    
    present.isEmpty(): false
    empty.isEmpty(): true
  2. value ← Hello

    35// Get value if present36if (present.isPresent()) {37    String value→ Hello = present.get();38    System.out.println("\nValue: " + valueHello);39}
    output
    Value: Hello
  3. else

    42    System.out.println("This won't print");43} else {44    System.out.println("Empty has no value");45}
    outputEmpty has no value
  4. num1 ← Optional[42], num2 ← Optional.empty

    47// Example with numbers48Optional<Integer> num1→ Optional[42] = Optional.of(42);49Optional<Integer> num2→ Optional.empty = Optional.ofNullable(null);5051System.out.println("\nNumbers:");52System.out.println("num1: " + num1Optional[42]);53System.out.println("num2: " + num2Optional.empty);54System.out.println("num1 present: " + num1.isPresent());55System.out.println("num2 present: " + num2.isPresent());
    output
    Numbers:
    num1: Optional[42]
    num2: Optional.empty
    num1 present: true
    num2 present: false
  1. present ← Optional[Hello], nullable ← null, maybe1 ← Optional.empty

    6public class CreatingOptional {7    public static void main(String[] args) {8        // Create Optional with value9        Optional<String> present→ Optional[Hello] = Optional.of("Hello");10        System.out.println("Present: " + presentOptional[Hello]);11        12        // Create Optional from nullable value13        String nullable→ null = null;14        Optional<String> maybe1→ Optional.empty = Optional.ofNullable(nullablenull);15        System.out.println("Maybe 1: " + maybe1Optional.empty);16        17        nullable→ null = null;18        Optional<String> maybe2→ Optional.empty = Optional.ofNullable(nullablenull);19        System.out.println("Maybe 2: " + maybe2Optional.empty);20        21        22        // Create empty Optional23        Optional<String> empty→ Optional.empty = Optional.empty();24        System.out.println("Empty: " + emptyOptional.empty);25        26        // Check if value is present27        System.out.println("\nChecking presence:");28        System.out.println("present.isPresent(): " + present.isPresent());29        System.out.println("empty.isPresent(): " + empty.isPresent());30        31        // isEmpty (Java 11+)32        System.out.println("\npresent.isEmpty(): " + present.isEmpty());33        System.out.println("empty.isEmpty(): " + empty.isEmpty());
    outputPresent: Optional[Hello]
    Maybe 1: Optional.empty
    Maybe 2: Optional.empty
    Empty: Optional.empty
    
    Checking presence:
    present.isPresent(): true
    empty.isPresent(): false
    
    present.isEmpty(): false
    empty.isEmpty(): true
  2. value ← Hello

    35// Get value if present36if (present.isPresent()) {37    String value→ Hello = present.get();38    System.out.println("\nValue: " + valueHello);39}
    output
    Value: Hello
  3. else

    42    System.out.println("This won't print");43} else {44    System.out.println("Empty has no value");45}
    outputEmpty has no value
  4. num1 ← Optional[42], num2 ← Optional.empty

    47// Example with numbers48Optional<Integer> num1→ Optional[42] = Optional.of(42);49Optional<Integer> num2→ Optional.empty = Optional.ofNullable(null);5051System.out.println("\nNumbers:");52System.out.println("num1: " + num1Optional[42]);53System.out.println("num2: " + num2Optional.empty);54System.out.println("num1 present: " + num1.isPresent());55System.out.println("num2 present: " + num2.isPresent());
    output
    Numbers:
    num1: Optional[42]
    num2: Optional.empty
    num1 present: true
    num2 present: false

Optional.of() for non-null, Optional.ofNullable() for maybe-null, Optional.empty() for absent.

Optional Container that may or may not contain a value. Makes null explicit.

Check and use values

Handle present and absent cases.

name
IfPresent.java
Replay: real traced execution (multi-file project)
// ifPresent and ifPresentOrElse
// Concept: ifPresent - execute action if value exists

import java.util.Optional;

public class IfPresent {
    public static void main(String[] args) {
        // ifPresent - do something if value exists
        Optional<String> name = Optional.of("Alice");

        System.out.println("Using ifPresent:");
        name.ifPresent(value -> System.out.println("  Hello, " + value));

        Optional<String> empty = Optional.empty();
        empty.ifPresent(value -> System.out.println("  This won't print"));


        // ifPresentOrElse (Java 9+)
        System.out.println("\nUsing ifPresentOrElse:");

        name.ifPresentOrElse(
            value -> System.out.println("  Found: " + value),
            () -> System.out.println("  Not found")
        );

        empty.ifPresentOrElse(
            value -> System.out.println("  Found: " + value),
            () -> System.out.println("  Not found")
        );

        // Process multiple optionals
        Optional<Integer>[] scores = new Optional[] {
            Optional.of(85),
            Optional.empty(),
            Optional.of(92),
            Optional.of(78)
        };

        System.out.println("\nProcessing scores:");
        for (int i = 0; i < scores.length; i++) {
            int index = i;
            scores[i].ifPresent(score ->
                System.out.println("  Score " + index + ": " + score)
            );
        }

        // Accumulate values
        System.out.println("\nAccumulating:");

        int[] sum = {0};
        int[] count = {0};

        for (Optional<Integer> score : scores) {
            score.ifPresent(value -> {
                sum[0] += value;
                count[0]++;
            });
        }

        if (count[0] > 0) {
            double average = (double) sum[0] / count[0];
            System.out.printf("  Average: %.1f%n", average);
        }

        // Log if missing
        System.out.println("\nLogging:");

        Optional<String> config = Optional.empty();

        config.ifPresentOrElse(
            value -> System.out.println("  Config: " + value),
            () -> System.out.println("  WARNING: Config not found")
        );

    }
}
// ifPresent and ifPresentOrElse
// Concept: ifPresent - execute action if value exists

import java.util.Optional;

public class IfPresent {
    public static void main(String[] args) {
        // ifPresent - do something if value exists
        Optional<String> name = Optional.of("Bob");

        System.out.println("Using ifPresent:");
        name.ifPresent(value -> System.out.println("  Hello, " + value));

        Optional<String> empty = Optional.empty();
        empty.ifPresent(value -> System.out.println("  This won't print"));


        // ifPresentOrElse (Java 9+)
        System.out.println("\nUsing ifPresentOrElse:");

        name.ifPresentOrElse(
            value -> System.out.println("  Found: " + value),
            () -> System.out.println("  Not found")
        );

        empty.ifPresentOrElse(
            value -> System.out.println("  Found: " + value),
            () -> System.out.println("  Not found")
        );

        // Process multiple optionals
        Optional<Integer>[] scores = new Optional[] {
            Optional.of(85),
            Optional.empty(),
            Optional.of(92),
            Optional.of(78)
        };

        System.out.println("\nProcessing scores:");
        for (int i = 0; i < scores.length; i++) {
            int index = i;
            scores[i].ifPresent(score ->
                System.out.println("  Score " + index + ": " + score)
            );
        }

        // Accumulate values
        System.out.println("\nAccumulating:");

        int[] sum = {0};
        int[] count = {0};

        for (Optional<Integer> score : scores) {
            score.ifPresent(value -> {
                sum[0] += value;
                count[0]++;
            });
        }

        if (count[0] > 0) {
            double average = (double) sum[0] / count[0];
            System.out.printf("  Average: %.1f%n", average);
        }

        // Log if missing
        System.out.println("\nLogging:");

        Optional<String> config = Optional.empty();

        config.ifPresentOrElse(
            value -> System.out.println("  Config: " + value),
            () -> System.out.println("  WARNING: Config not found")
        );

    }
}
// ifPresent and ifPresentOrElse
// Concept: ifPresent - execute action if value exists

import java.util.Optional;

public class IfPresent {
    public static void main(String[] args) {
        // ifPresent - do something if value exists
        Optional<String> name = Optional.empty();

        System.out.println("Using ifPresent:");
        name.ifPresent(value -> System.out.println("  Hello, " + value));

        Optional<String> empty = Optional.empty();
        empty.ifPresent(value -> System.out.println("  This won't print"));


        // ifPresentOrElse (Java 9+)
        System.out.println("\nUsing ifPresentOrElse:");

        name.ifPresentOrElse(
            value -> System.out.println("  Found: " + value),
            () -> System.out.println("  Not found")
        );

        empty.ifPresentOrElse(
            value -> System.out.println("  Found: " + value),
            () -> System.out.println("  Not found")
        );

        // Process multiple optionals
        Optional<Integer>[] scores = new Optional[] {
            Optional.of(85),
            Optional.empty(),
            Optional.of(92),
            Optional.of(78)
        };

        System.out.println("\nProcessing scores:");
        for (int i = 0; i < scores.length; i++) {
            int index = i;
            scores[i].ifPresent(score ->
                System.out.println("  Score " + index + ": " + score)
            );
        }

        // Accumulate values
        System.out.println("\nAccumulating:");

        int[] sum = {0};
        int[] count = {0};

        for (Optional<Integer> score : scores) {
            score.ifPresent(value -> {
                sum[0] += value;
                count[0]++;
            });
        }

        if (count[0] > 0) {
            double average = (double) sum[0] / count[0];
            System.out.printf("  Average: %.1f%n", average);
        }

        // Log if missing
        System.out.println("\nLogging:");

        Optional<String> config = Optional.empty();

        config.ifPresentOrElse(
            value -> System.out.println("  Config: " + value),
            () -> System.out.println("  WARNING: Config not found")
        );

    }
}
  1. name ← Optional[Alice], empty ← Optional.empty

    6public class IfPresent {7    public static void main(String[] args) {8        // ifPresent - do something if value exists9        Optional<String> name→ Optional[Alice] = Optional.of("Alice");10        //@name=Optional.of("Alice"), Optional.of("Bob"), Optional.empty()11        12        System.out.println("Using ifPresent:");13        name.ifPresent(value -> System.out.println("  Hello, " + value));14        15        Optional<String> empty→ Optional.empty = Optional.empty();16        empty.ifPresent(value -> System.out.println("  This won't print"));17        18        //@help h119        // ifPresent(Consumer) executes lambda only if value present20        // Safer than isPresent() + get() pattern21        // No risk of forgetting to check22        //@end23        24        // ifPresentOrElse (Java 9+)25        System.out.println("\nUsing ifPresentOrElse:");26        27        name.ifPresentOrElse(28            value -> System.out.println("  Found: " + value),29            () -> System.out.println("  Not found")30        );31        32        empty.ifPresentOrElse(33            value -> System.out.println("  Found: " + value),34            () -> System.out.println("  Not found")35        );36        37        // Process multiple optionals38        Optional<Integer>[] scores = new Optional[] {39            Optional.of(85),40            Optional.empty(),41            Optional.of(92),42            Optional.of(78)43        };44        45        System.out.println("\nProcessing scores:");46        for (int i = 0; i < scores.length; i++) {
    outputUsing ifPresent:
    
    Using ifPresentOrElse:
    
    Processing scores:
  2. index ← 0

    pass 1 of 4
    45System.out.println("\nProcessing scores:");46for (int i0 = 0; i < scores.length4; i++) {47    int index→ 0 = i;48    scores[i]Optional[85].ifPresent(score -> 49        System.out.println("  Score " + index + ": " + score)50    );51}
    All 4 passes — pass 1 is the card above
    passiscores[i]index
    10Optional[85]0
    21Optional.empty1
    32Optional[92]2
    43Optional[78]3
  3. int[] sum = {0};

    53// Accumulate values54System.out.println("\nAccumulating:");5556int[] sum = {0};57int[] count = {0};
    output
    Accumulating:
  4. for (Optional<Integer> score : scores)

    pass 1 of 4
    59for (Optional<Integer> scoreOptional[85] : scores) {60    score.ifPresent(value -> {61        sum[0] += value;62        count[0]++;63    });64}
    All 4 passes — pass 1 is the card above
    passscorecount[0]sum[0]average
    1Optional[85]
    2Optional.empty
    3Optional[92]
    4Optional[78]325585.0
  5. value ->

    pass 1 of 3
    59for (Optional<Integer> score : scores) {60    score.ifPresent(value -> {61        sum[0] += value;62        count[0]++;63    });64}
    All 3 passes — pass 1 is the card above
    passcount[0]sum[0]average
    1
    2
    3325585.0
  6. average ← 85.0

    66if (count[0]3 > 0) {67    double average→ 85.0 = (double) sum[0]255 / count[0]3;68    System.out.printf("  Average: %.1f%n", average85.0);69}
  7. config ← Optional.empty

    71// Log if missing72System.out.println("\nLogging:");7374Optional<String> config→ Optional.empty = Optional.empty();7576config.ifPresentOrElse(77    value -> System.out.println("  Config: " + value),78    () -> System.out.println("  WARNING: Config not found")79);
    output
    Logging:
  1. name ← Optional[Bob], empty ← Optional.empty

    6public class IfPresent {7    public static void main(String[] args) {8        // ifPresent - do something if value exists9        Optional<String> name→ Optional[Bob] = Optional.of("Bob");10        11        System.out.println("Using ifPresent:");12        name.ifPresent(value -> System.out.println("  Hello, " + value));13        14        Optional<String> empty→ Optional.empty = Optional.empty();15        empty.ifPresent(value -> System.out.println("  This won't print"));16        17        18        // ifPresentOrElse (Java 9+)19        System.out.println("\nUsing ifPresentOrElse:");20        21        name.ifPresentOrElse(22            value -> System.out.println("  Found: " + value),23            () -> System.out.println("  Not found")24        );25        26        empty.ifPresentOrElse(27            value -> System.out.println("  Found: " + value),28            () -> System.out.println("  Not found")29        );30        31        // Process multiple optionals32        Optional<Integer>[] scores = new Optional[] {33            Optional.of(85),34            Optional.empty(),35            Optional.of(92),36            Optional.of(78)37        };38        39        System.out.println("\nProcessing scores:");40        for (int i = 0; i < scores.length; i++) {
    outputUsing ifPresent:
    
    Using ifPresentOrElse:
    
    Processing scores:
  2. index ← 0

    pass 1 of 4
    39System.out.println("\nProcessing scores:");40for (int i0 = 0; i < scores.length4; i++) {41    int index→ 0 = i;42    scores[i]Optional[85].ifPresent(score -> 43        System.out.println("  Score " + index + ": " + score)44    );45}
    All 4 passes — pass 1 is the card above
    passiscores[i]index
    10Optional[85]0
    21Optional.empty1
    32Optional[92]2
    43Optional[78]3
  3. int[] sum = {0};

    47// Accumulate values48System.out.println("\nAccumulating:");4950int[] sum = {0};51int[] count = {0};
    output
    Accumulating:
  4. for (Optional<Integer> score : scores)

    pass 1 of 4
    53for (Optional<Integer> scoreOptional[85] : scores) {54    score.ifPresent(value -> {55        sum[0] += value;56        count[0]++;57    });58}
    All 4 passes — pass 1 is the card above
    passscorecount[0]sum[0]average
    1Optional[85]
    2Optional.empty
    3Optional[92]
    4Optional[78]325585.0
  5. value ->

    pass 1 of 3
    53for (Optional<Integer> score : scores) {54    score.ifPresent(value -> {55        sum[0] += value;56        count[0]++;57    });58}
    All 3 passes — pass 1 is the card above
    passcount[0]sum[0]average
    1
    2
    3325585.0
  6. average ← 85.0

    60if (count[0]3 > 0) {61    double average→ 85.0 = (double) sum[0]255 / count[0]3;62    System.out.printf("  Average: %.1f%n", average85.0);63}
  7. config ← Optional.empty

    65// Log if missing66System.out.println("\nLogging:");6768Optional<String> config→ Optional.empty = Optional.empty();6970config.ifPresentOrElse(71    value -> System.out.println("  Config: " + value),72    () -> System.out.println("  WARNING: Config not found")73);
    output
    Logging:
  1. name ← Optional.empty, empty ← Optional.empty

    6public class IfPresent {7    public static void main(String[] args) {8        // ifPresent - do something if value exists9        Optional<String> name→ Optional.empty = Optional.empty();10        11        System.out.println("Using ifPresent:");12        name.ifPresent(value -> System.out.println("  Hello, " + value));13        14        Optional<String> empty→ Optional.empty = Optional.empty();15        empty.ifPresent(value -> System.out.println("  This won't print"));16        17        18        // ifPresentOrElse (Java 9+)19        System.out.println("\nUsing ifPresentOrElse:");20        21        name.ifPresentOrElse(22            value -> System.out.println("  Found: " + value),23            () -> System.out.println("  Not found")24        );25        26        empty.ifPresentOrElse(27            value -> System.out.println("  Found: " + value),28            () -> System.out.println("  Not found")29        );30        31        // Process multiple optionals32        Optional<Integer>[] scores = new Optional[] {33            Optional.of(85),34            Optional.empty(),35            Optional.of(92),36            Optional.of(78)37        };38        39        System.out.println("\nProcessing scores:");40        for (int i = 0; i < scores.length; i++) {
    outputUsing ifPresent:
    
    Using ifPresentOrElse:
    
    Processing scores:
  2. index ← 0

    pass 1 of 4
    39System.out.println("\nProcessing scores:");40for (int i0 = 0; i < scores.length4; i++) {41    int index→ 0 = i;42    scores[i]Optional[85].ifPresent(score -> 43        System.out.println("  Score " + index + ": " + score)44    );45}
    All 4 passes — pass 1 is the card above
    passiscores[i]index
    10Optional[85]0
    21Optional.empty1
    32Optional[92]2
    43Optional[78]3
  3. int[] sum = {0};

    47// Accumulate values48System.out.println("\nAccumulating:");4950int[] sum = {0};51int[] count = {0};
    output
    Accumulating:
  4. for (Optional<Integer> score : scores)

    pass 1 of 4
    53for (Optional<Integer> scoreOptional[85] : scores) {54    score.ifPresent(value -> {55        sum[0] += value;56        count[0]++;57    });58}
    All 4 passes — pass 1 is the card above
    passscorecount[0]sum[0]average
    1Optional[85]
    2Optional.empty
    3Optional[92]
    4Optional[78]325585.0
  5. value ->

    pass 1 of 3
    53for (Optional<Integer> score : scores) {54    score.ifPresent(value -> {55        sum[0] += value;56        count[0]++;57    });58}
    All 3 passes — pass 1 is the card above
    passcount[0]sum[0]average
    1
    2
    3325585.0
  6. average ← 85.0

    60if (count[0]3 > 0) {61    double average→ 85.0 = (double) sum[0]255 / count[0]3;62    System.out.printf("  Average: %.1f%n", average85.0);63}
  7. config ← Optional.empty

    65// Log if missing66System.out.println("\nLogging:");6768Optional<String> config→ Optional.empty = Optional.empty();6970config.ifPresentOrElse(71    value -> System.out.println("  Config: " + value),72    () -> System.out.println("  WARNING: Config not found")73);
    output
    Logging:

ifPresent() runs code only when value exists. Avoids null checks.

Provide defaults

Get value or use fallback.

name
Defaults.java
Replay: real traced execution (multi-file project)
// orElse, orElseGet, orElseThrow
// Concept: default values - providing fallbacks

import java.util.Optional;

public class Defaults {
    public static void main(String[] args) {
        // orElse - provide default value
        Optional<String> name = Optional.of("Alice");
        Optional<String> empty = Optional.empty();

        String result1 = name.orElse("Unknown");
        String result2 = empty.orElse("Unknown");

        System.out.println("orElse:");
        System.out.println("  name: " + result1);
        System.out.println("  empty: " + result2);


        // orElseGet - compute default lazily
        System.out.println("\norElseGet:");

        String r1 = name.orElseGet(() -> {
            System.out.println("  Computing default...");
            return "Generated";
        });
        System.out.println("  Result: " + r1);

        String r2 = empty.orElseGet(() -> {
            System.out.println("  Computing default...");
            return "Generated";
        });
        System.out.println("  Result: " + r2);

        // orElse vs orElseGet difference
        System.out.println("\nDifference:");

        System.out.println("With orElse:");
        String x1 = name.orElse(expensiveDefault());

        System.out.println("\nWith orElseGet:");
        String x2 = name.orElseGet(() -> expensiveDefault());

        // orElseThrow - require value
        System.out.println("\norElseThrow:");

        try {
            String value = name.orElseThrow();
            System.out.println("  Got value: " + value);
        } catch (Exception e) {
            System.out.println("  Error: " + e);
        }

        try {
            String value = empty.orElseThrow();
            System.out.println("  Got value: " + value);
        } catch (Exception e) {
            System.out.println("  Error: " + e.getClass().getSimpleName());
        }

        // orElseThrow with custom exception
        try {
            String value = empty.orElseThrow(() ->
                new IllegalArgumentException("Value required")
            );
        } catch (IllegalArgumentException e) {
            System.out.println("  Custom error: " + e.getMessage());
        }

        // Practical examples
        System.out.println("\nPractical:");

        Optional<Integer> port = Optional.empty();
        int serverPort = port.orElse(8080);
        System.out.println("  Server port: " + serverPort);

        Optional<String> env = Optional.ofNullable(null);
        String environment = env.orElseGet(() -> {
            System.out.println("  Reading from config...");
            return "development";
        });
        System.out.println("  Environment: " + environment);

        Optional<String> apiKey = Optional.empty();
        try {
            String key = apiKey.orElseThrow(() ->
                new RuntimeException("API key not configured")
            );
        } catch (RuntimeException e) {
            System.out.println("  " + e.getMessage());
        }
    }

    static String expensiveDefault() {
        System.out.println("  Expensive computation!");
        return "Default";
    }
}
// orElse, orElseGet, orElseThrow
// Concept: default values - providing fallbacks

import java.util.Optional;

public class Defaults {
    public static void main(String[] args) {
        // orElse - provide default value
        Optional<String> name = Optional.empty();
        Optional<String> empty = Optional.empty();

        String result1 = name.orElse("Unknown");
        String result2 = empty.orElse("Unknown");

        System.out.println("orElse:");
        System.out.println("  name: " + result1);
        System.out.println("  empty: " + result2);


        // orElseGet - compute default lazily
        System.out.println("\norElseGet:");

        String r1 = name.orElseGet(() -> {
            System.out.println("  Computing default...");
            return "Generated";
        });
        System.out.println("  Result: " + r1);

        String r2 = empty.orElseGet(() -> {
            System.out.println("  Computing default...");
            return "Generated";
        });
        System.out.println("  Result: " + r2);

        // orElse vs orElseGet difference
        System.out.println("\nDifference:");

        System.out.println("With orElse:");
        String x1 = name.orElse(expensiveDefault());

        System.out.println("\nWith orElseGet:");
        String x2 = name.orElseGet(() -> expensiveDefault());

        // orElseThrow - require value
        System.out.println("\norElseThrow:");

        try {
            String value = name.orElseThrow();
            System.out.println("  Got value: " + value);
        } catch (Exception e) {
            System.out.println("  Error: " + e);
        }

        try {
            String value = empty.orElseThrow();
            System.out.println("  Got value: " + value);
        } catch (Exception e) {
            System.out.println("  Error: " + e.getClass().getSimpleName());
        }

        // orElseThrow with custom exception
        try {
            String value = empty.orElseThrow(() ->
                new IllegalArgumentException("Value required")
            );
        } catch (IllegalArgumentException e) {
            System.out.println("  Custom error: " + e.getMessage());
        }

        // Practical examples
        System.out.println("\nPractical:");

        Optional<Integer> port = Optional.empty();
        int serverPort = port.orElse(8080);
        System.out.println("  Server port: " + serverPort);

        Optional<String> env = Optional.ofNullable(null);
        String environment = env.orElseGet(() -> {
            System.out.println("  Reading from config...");
            return "development";
        });
        System.out.println("  Environment: " + environment);

        Optional<String> apiKey = Optional.empty();
        try {
            String key = apiKey.orElseThrow(() ->
                new RuntimeException("API key not configured")
            );
        } catch (RuntimeException e) {
            System.out.println("  " + e.getMessage());
        }
    }

    static String expensiveDefault() {
        System.out.println("  Expensive computation!");
        return "Default";
    }
}
  1. name ← Optional[Alice], empty ← Optional.empty, result1 ← Alice

    6public class Defaults {7    public static void main(String[] args) {8        // orElse - provide default value9        Optional<String> name→ Optional[Alice] = Optional.of("Alice");10        //@name=Optional.of("Alice"), Optional.empty()11        Optional<String> empty→ Optional.empty = Optional.empty();12        13        String result1→ Alice = name.orElse("Unknown");14        String result2→ Unknown = empty.orElse("Unknown");15        16        System.out.println("orElse:");17        System.out.println("  name: " + result1Alice);18        System.out.println("  empty: " + result2Unknown);19        20        //@help h121        // orElse(default) - return value or default22        // orElseGet(Supplier) - compute default only if needed23        // orElseThrow() - throw exception if empty24        //@end25        26        // orElseGet - compute default lazily27        System.out.println("\norElseGet:");28        29        String r1→ Alice = name.orElseGet(() -> {30            System.out.println("  Computing default...");31            return "Generated";32        });33        System.out.println("  Result: " + r1Alice);34        35        String r2 = empty.orElseGet(() -> {36            System.out.println("  Computing default...");37            return "Generated";38        });39        System.out.println("  Result: " + r2);
    outputorElse:
      name: Alice
      empty: Unknown
    
    orElseGet:
      Result: Alice
  2. () ->

    35String r2 = empty.orElseGet(() -> {36    System.out.println("  Computing default...");37    return "Generated";38});
    output  Computing default...
  3. r2 ← Generated

    35String r2→ Generated = empty.orElseGet(() -> {36    System.out.println("  Computing default...");37    return "Generated";38});39System.out.println("  Result: " + r2Generated);4041// orElse vs orElseGet difference42System.out.println("\nDifference:");4344System.out.println("With orElse:");45String x1 = name.orElse(expensiveDefault());
    output  Result: Generated
    
    Difference:
    With orElse:
  4. static String expensiveDefault()

    100static String expensiveDefault() {101    System.out.println("  Expensive computation!");102    return "Default";103}
    output  Expensive computation!
  5. x1 ← Alice, x2 ← Alice

    44System.out.println("With orElse:");45String x1→ Alice = name.orElse(expensiveDefault());4647System.out.println("\nWith orElseGet:");48String x2→ Alice = name.orElseGet(() -> expensiveDefault());4950// orElseThrow - require value51System.out.println("\norElseThrow:");
    output
    With orElseGet:
    
    orElseThrow:
  6. value ← Alice

    53try {54    String value→ Alice = name.orElseThrow();55    System.out.println("  Got value: " + valueAlice);56} catch (Exception e) {
    output  Got value: Alice
  7. catch (Exception e)

    62    System.out.println("  Got value: " + value);63} catch (Exception ejava.util.NoSuchElementException: No value present) {64    System.out.println("  Error: " + e.getClass().getSimpleName());65}
    output  Error: NoSuchElementException
  8. catch (IllegalArgumentException e)

    71    );72} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Value required) {73    System.out.println("  Custom error: " + e.getMessage());74}
    output  Custom error: Value required
  9. port ← Optional.empty, serverPort ← 8080, env ← Optional.empty

    76// Practical examples77System.out.println("\nPractical:");7879Optional<Integer> port→ Optional.empty = Optional.empty();80int serverPort→ 8080 = port.orElse(8080);81System.out.println("  Server port: " + serverPort8080);8283Optional<String> env→ Optional.empty = Optional.ofNullable(null);84String environment = env.orElseGet(() -> {85    System.out.println("  Reading from config...");86    return "development";87});88System.out.println("  Environment: " + environment);
    output
    Practical:
      Server port: 8080
  10. () ->

    83Optional<String> env = Optional.ofNullable(null);84String environment = env.orElseGet(() -> {85    System.out.println("  Reading from config...");86    return "development";87});
    output  Reading from config...
  11. environment ← development, apiKey ← Optional.empty

    83Optional<String> env = Optional.ofNullable(null);84String environment→ development = env.orElseGet(() -> {85    System.out.println("  Reading from config...");86    return "development";87});88System.out.println("  Environment: " + environmentdevelopment);8990Optional<String> apiKey→ Optional.empty = Optional.empty();91try {
    output  Environment: development
  12. catch (RuntimeException e)

    94    );95} catch (RuntimeException ejava.lang.RuntimeException: API key not configured) {96    System.out.println("  " + e.getMessage());97}
    output  API key not configured
  1. name ← Optional.empty, empty ← Optional.empty, result1 ← Unknown

    6public class Defaults {7    public static void main(String[] args) {8        // orElse - provide default value9        Optional<String> name→ Optional.empty = Optional.empty();10        Optional<String> empty→ Optional.empty = Optional.empty();11        12        String result1→ Unknown = name.orElse("Unknown");13        String result2→ Unknown = empty.orElse("Unknown");14        15        System.out.println("orElse:");16        System.out.println("  name: " + result1Unknown);17        System.out.println("  empty: " + result2Unknown);18        19        20        // orElseGet - compute default lazily21        System.out.println("\norElseGet:");22        23        String r1 = name.orElseGet(() -> {24            System.out.println("  Computing default...");25            return "Generated";26        });27        System.out.println("  Result: " + r1);
    outputorElse:
      name: Unknown
      empty: Unknown
    
    orElseGet:
  2. () ->

    23String r1 = name.orElseGet(() -> {24    System.out.println("  Computing default...");25    return "Generated";26});
    output  Computing default...
  3. r1 ← Generated

    23String r1→ Generated = name.orElseGet(() -> {24    System.out.println("  Computing default...");25    return "Generated";26});27System.out.println("  Result: " + r1Generated);2829String r2 = empty.orElseGet(() -> {30    System.out.println("  Computing default...");31    return "Generated";32});33System.out.println("  Result: " + r2);
    output  Result: Generated
  4. () ->

    29String r2 = empty.orElseGet(() -> {30    System.out.println("  Computing default...");31    return "Generated";32});
    output  Computing default...
  5. r2 ← Generated

    29String r2→ Generated = empty.orElseGet(() -> {30    System.out.println("  Computing default...");31    return "Generated";32});33System.out.println("  Result: " + r2Generated);3435// orElse vs orElseGet difference36System.out.println("\nDifference:");3738System.out.println("With orElse:");39String x1 = name.orElse(expensiveDefault());
    output  Result: Generated
    
    Difference:
    With orElse:
  6. static String expensiveDefault()

    pass 1 of 2
    94static String expensiveDefault() {95    System.out.println("  Expensive computation!");96    return "Default";97}
    output  Expensive computation!
  7. x1 ← Default

    38System.out.println("With orElse:");39String x1→ Default = name.orElse(expensiveDefault());4041System.out.println("\nWith orElseGet:");42String x2 = name.orElseGet(() -> expensiveDefault());
    output
    With orElseGet:
  8. static String expensiveDefault()

    pass 2 of 2
    94static String expensiveDefault() {95    System.out.println("  Expensive computation!");96    return "Default";97}
    output  Expensive computation!
  9. x2 ← Default

    41System.out.println("\nWith orElseGet:");42String x2→ Default = name.orElseGet(() -> expensiveDefault());4344// orElseThrow - require value45System.out.println("\norElseThrow:");
    output
    orElseThrow:
  10. catch (Exception e)

    49    System.out.println("  Got value: " + value);50} catch (Exception ejava.util.NoSuchElementException: No value present) {51    System.out.println("  Error: " + ejava.util.NoSuchElementException: No value present);52}
    output  Error: java.util.NoSuchElementException: No value present
  11. catch (Exception e)

    56    System.out.println("  Got value: " + value);57} catch (Exception ejava.util.NoSuchElementException: No value present) {58    System.out.println("  Error: " + e.getClass().getSimpleName());59}
    output  Error: NoSuchElementException
  12. catch (IllegalArgumentException e)

    65    );66} catch (IllegalArgumentException ejava.lang.IllegalArgumentException: Value required) {67    System.out.println("  Custom error: " + e.getMessage());68}
    output  Custom error: Value required
  13. port ← Optional.empty, serverPort ← 8080, env ← Optional.empty

    70// Practical examples71System.out.println("\nPractical:");7273Optional<Integer> port→ Optional.empty = Optional.empty();74int serverPort→ 8080 = port.orElse(8080);75System.out.println("  Server port: " + serverPort8080);7677Optional<String> env→ Optional.empty = Optional.ofNullable(null);78String environment = env.orElseGet(() -> {79    System.out.println("  Reading from config...");80    return "development";81});82System.out.println("  Environment: " + environment);
    output
    Practical:
      Server port: 8080
  14. () ->

    77Optional<String> env = Optional.ofNullable(null);78String environment = env.orElseGet(() -> {79    System.out.println("  Reading from config...");80    return "development";81});
    output  Reading from config...
  15. environment ← development, apiKey ← Optional.empty

    77Optional<String> env = Optional.ofNullable(null);78String environment→ development = env.orElseGet(() -> {79    System.out.println("  Reading from config...");80    return "development";81});82System.out.println("  Environment: " + environmentdevelopment);8384Optional<String> apiKey→ Optional.empty = Optional.empty();85try {
    output  Environment: development
  16. catch (RuntimeException e)

    88    );89} catch (RuntimeException ejava.lang.RuntimeException: API key not configured) {90    System.out.println("  " + e.getMessage());91}
    output  API key not configured

orElse() provides default. orElseGet() computes default lazily.

orElse Get value if present, otherwise use default: `opt.orElse("default")`.

Transform with map

Apply function to Optional's value.

name
MapFlatmap.java
Replay: real traced execution (multi-file project)
// map and flatMap transformations
// Concept: transformation - converting Optional values

import java.util.Optional;

public class MapFlatmap {
    public static void main(String[] args) {
        // map - transform value if present
        Optional<String> name = Optional.of("alice");

        Optional<String> upper = name.map(s -> s.toUpperCase());
        System.out.println("Original: " + name);
        System.out.println("Uppercase: " + upper);

        Optional<Integer> length = name.map(s -> s.length());
        System.out.println("Length: " + length);

        // map on empty Optional
        Optional<String> empty = Optional.empty();
        Optional<String> result = empty.map(s -> s.toUpperCase());
        System.out.println("\nEmpty mapped: " + result);


        // Chain multiple maps
        System.out.println("\nChained maps:");

        Optional<String> processed = Optional.of("  hello  ")
            .map(s -> s.trim())
            .map(s -> s.toUpperCase())
            .map(s -> s + "!");

        System.out.println("Result: " + processed.orElse(""));

        // flatMap - when function returns Optional
        Optional<String> userId = Optional.of("123");

        Optional<User> user = userId.flatMap(id -> findUser(id));
        System.out.println("\nUser: " + user);

        Optional<String> email = userId
            .flatMap(id -> findUser(id))
            .map(u -> u.email);
        System.out.println("Email: " + email);

        // map vs flatMap
        System.out.println("\nmap vs flatMap:");

        // map wraps result in Optional
        Optional<Optional<User>> nested = userId.map(id -> findUser(id));
        System.out.println("map result: " + nested);

        // flatMap doesn't wrap
        Optional<User> flat = userId.flatMap(id -> findUser(id));
        System.out.println("flatMap result: " + flat);

        // Practical transformation pipeline
        System.out.println("\nPipeline:");

        Optional<String> input = Optional.of("42");

        Optional<String> output = input
            .map(s -> Integer.parseInt(s))
            .map(n -> n * 2)
            .map(n -> "Result: " + n);

        output.ifPresent(System.out::println);

        // Safe navigation
        Optional<Integer> price = Optional.of("Product123")
            .flatMap(id -> findProduct(id))
            .map(p -> p.price);

        System.out.println("\nProduct price: " + price.orElse(0));

    }

    static Optional<User> findUser(String id) {
        if (id.equals("123")) {
            return Optional.of(new User("Alice", "alice@example.com"));
        }
        return Optional.empty();
    }

    static Optional<Product> findProduct(String id) {
        if (id.equals("Product123")) {
            return Optional.of(new Product("Laptop", 999));
        }
        return Optional.empty();
    }

    static class User {
        String name;
        String email;
        User(String name, String email) {
            this.name = name;
            this.email = email;
        }
        public String toString() {
            return "User(" + name + ", " + email + ")";
        }
    }

    static class Product {
        String name;
        int price;
        Product(String name, int price) {
            this.name = name;
            this.price = price;
        }
    }
}
// map and flatMap transformations
// Concept: transformation - converting Optional values

import java.util.Optional;

public class MapFlatmap {
    public static void main(String[] args) {
        // map - transform value if present
        Optional<String> name = Optional.of("bob");

        Optional<String> upper = name.map(s -> s.toUpperCase());
        System.out.println("Original: " + name);
        System.out.println("Uppercase: " + upper);

        Optional<Integer> length = name.map(s -> s.length());
        System.out.println("Length: " + length);

        // map on empty Optional
        Optional<String> empty = Optional.empty();
        Optional<String> result = empty.map(s -> s.toUpperCase());
        System.out.println("\nEmpty mapped: " + result);


        // Chain multiple maps
        System.out.println("\nChained maps:");

        Optional<String> processed = Optional.of("  hello  ")
            .map(s -> s.trim())
            .map(s -> s.toUpperCase())
            .map(s -> s + "!");

        System.out.println("Result: " + processed.orElse(""));

        // flatMap - when function returns Optional
        Optional<String> userId = Optional.of("123");

        Optional<User> user = userId.flatMap(id -> findUser(id));
        System.out.println("\nUser: " + user);

        Optional<String> email = userId
            .flatMap(id -> findUser(id))
            .map(u -> u.email);
        System.out.println("Email: " + email);

        // map vs flatMap
        System.out.println("\nmap vs flatMap:");

        // map wraps result in Optional
        Optional<Optional<User>> nested = userId.map(id -> findUser(id));
        System.out.println("map result: " + nested);

        // flatMap doesn't wrap
        Optional<User> flat = userId.flatMap(id -> findUser(id));
        System.out.println("flatMap result: " + flat);

        // Practical transformation pipeline
        System.out.println("\nPipeline:");

        Optional<String> input = Optional.of("42");

        Optional<String> output = input
            .map(s -> Integer.parseInt(s))
            .map(n -> n * 2)
            .map(n -> "Result: " + n);

        output.ifPresent(System.out::println);

        // Safe navigation
        Optional<Integer> price = Optional.of("Product123")
            .flatMap(id -> findProduct(id))
            .map(p -> p.price);

        System.out.println("\nProduct price: " + price.orElse(0));

    }

    static Optional<User> findUser(String id) {
        if (id.equals("123")) {
            return Optional.of(new User("Alice", "alice@example.com"));
        }
        return Optional.empty();
    }

    static Optional<Product> findProduct(String id) {
        if (id.equals("Product123")) {
            return Optional.of(new Product("Laptop", 999));
        }
        return Optional.empty();
    }

    static class User {
        String name;
        String email;
        User(String name, String email) {
            this.name = name;
            this.email = email;
        }
        public String toString() {
            return "User(" + name + ", " + email + ")";
        }
    }

    static class Product {
        String name;
        int price;
        Product(String name, int price) {
            this.name = name;
            this.price = price;
        }
    }
}
// map and flatMap transformations
// Concept: transformation - converting Optional values

import java.util.Optional;

public class MapFlatmap {
    public static void main(String[] args) {
        // map - transform value if present
        Optional<String> name = Optional.empty();

        Optional<String> upper = name.map(s -> s.toUpperCase());
        System.out.println("Original: " + name);
        System.out.println("Uppercase: " + upper);

        Optional<Integer> length = name.map(s -> s.length());
        System.out.println("Length: " + length);

        // map on empty Optional
        Optional<String> empty = Optional.empty();
        Optional<String> result = empty.map(s -> s.toUpperCase());
        System.out.println("\nEmpty mapped: " + result);


        // Chain multiple maps
        System.out.println("\nChained maps:");

        Optional<String> processed = Optional.of("  hello  ")
            .map(s -> s.trim())
            .map(s -> s.toUpperCase())
            .map(s -> s + "!");

        System.out.println("Result: " + processed.orElse(""));

        // flatMap - when function returns Optional
        Optional<String> userId = Optional.of("123");

        Optional<User> user = userId.flatMap(id -> findUser(id));
        System.out.println("\nUser: " + user);

        Optional<String> email = userId
            .flatMap(id -> findUser(id))
            .map(u -> u.email);
        System.out.println("Email: " + email);

        // map vs flatMap
        System.out.println("\nmap vs flatMap:");

        // map wraps result in Optional
        Optional<Optional<User>> nested = userId.map(id -> findUser(id));
        System.out.println("map result: " + nested);

        // flatMap doesn't wrap
        Optional<User> flat = userId.flatMap(id -> findUser(id));
        System.out.println("flatMap result: " + flat);

        // Practical transformation pipeline
        System.out.println("\nPipeline:");

        Optional<String> input = Optional.of("42");

        Optional<String> output = input
            .map(s -> Integer.parseInt(s))
            .map(n -> n * 2)
            .map(n -> "Result: " + n);

        output.ifPresent(System.out::println);

        // Safe navigation
        Optional<Integer> price = Optional.of("Product123")
            .flatMap(id -> findProduct(id))
            .map(p -> p.price);

        System.out.println("\nProduct price: " + price.orElse(0));

    }

    static Optional<User> findUser(String id) {
        if (id.equals("123")) {
            return Optional.of(new User("Alice", "alice@example.com"));
        }
        return Optional.empty();
    }

    static Optional<Product> findProduct(String id) {
        if (id.equals("Product123")) {
            return Optional.of(new Product("Laptop", 999));
        }
        return Optional.empty();
    }

    static class User {
        String name;
        String email;
        User(String name, String email) {
            this.name = name;
            this.email = email;
        }
        public String toString() {
            return "User(" + name + ", " + email + ")";
        }
    }

    static class Product {
        String name;
        int price;
        Product(String name, int price) {
            this.name = name;
            this.price = price;
        }
    }
}
  1. name ← Optional[alice], upper ← Optional[ALICE], length ← Optional[5]

    6public class MapFlatmap {7    public static void main(String[] args) {8        // map - transform value if present9        Optional<String> name→ Optional[alice] = Optional.of("alice");10        //@name=Optional.of("alice"), Optional.of("bob"), Optional.empty()11        12        Optional<String> upper→ Optional[ALICE] = name.map(s -> s.toUpperCase());13        System.out.println("Original: " + nameOptional[alice]);14        System.out.println("Uppercase: " + upperOptional[ALICE]);15        16        Optional<Integer> length→ Optional[5] = name.map(s -> s.length());17        System.out.println("Length: " + lengthOptional[5]);18        19        // map on empty Optional20        Optional<String> empty→ Optional.empty = Optional.empty();21        Optional<String> result→ Optional.empty = empty.map(s -> s.toUpperCase());22        System.out.println("\nEmpty mapped: " + resultOptional.empty);23        24        //@help h125        // map(Function) transforms value, returns Optional<T>26        // flatMap(Function) when function returns Optional27        // map chains transformations safely28        //@end29        30        // Chain multiple maps31        System.out.println("\nChained maps:");32        33        Optional<String> processed→ Optional[HELLO!] = Optional.of("  hello  ")34            .map(s -> s.trim())35            .map(s -> s.toUpperCase())36            .map(s -> s + "!");37        38        System.out.println("Result: " + processed.orElse(""));39        40        // flatMap - when function returns Optional41        Optional<String> userId→ Optional[123] = Optional.of("123");42        43        Optional<User> user = userId.flatMap(id -> findUser(id));44        System.out.println("\nUser: " + user);
    outputOriginal: Optional[alice]
    Uppercase: Optional[ALICE]
    Length: Optional[5]
    
    Empty mapped: Optional.empty
    
    Chained maps:
    Result: HELLO!
  2. static Optional<User> findUser(String id)

    pass 1 of 4
    83static Optional<User> findUser(String id123) {84    if (id.equals("123")) {
    All 4 passes — pass 1 is the card above
    passnamethis.namethis.priceprice
    1
    2
    3
    4LaptopLaptop999999 Optional[999]
  3. if (id.equals("123"))

    pass 1 of 4
    83static Optional<User> findUser(String id) {84    if (id.equals("123")) {85        return Optional.of(new User("Alice", "alice@example.com"));86    }
    All 4 passes — pass 1 is the card above
    passidnamethis.namethis.priceprice
    1
    2
    3
    4Product123LaptopLaptop999999 Optional[999]
  4. this.name ← Alice, this.email ← alice@example.com, user ← Optional[User(Alice, alice@example.com)]

    pass 1 of 4
    43    Optional<User> user→ Optional[User(Alice, alice@example.com)] = userId.flatMap(id -> findUser(id));44    System.out.println("\nUser: " + userOptional[User(Alice, alice@example.com)]);45    46    Optional<String> email = userId47        .flatMap(id -> findUser(id))48        .map(u -> u.email);49    System.out.println("Email: " + email);50    51    // map vs flatMap52    System.out.println("\nmap vs flatMap:");53    54    // map wraps result in Optional55    Optional<Optional<User>> nested = userId.map(id -> findUser(id));56    System.out.println("map result: " + nested);57    58    // flatMap doesn't wrap59    Optional<User> flat = userId.flatMap(id -> findUser(id));60    System.out.println("flatMap result: " + flat);61    62    // Practical transformation pipeline63    System.out.println("\nPipeline:");64    65    Optional<String> input = Optional.of("42");66    67    Optional<String> output = input68        .map(s -> Integer.parseInt(s))69        .map(n -> n * 2)70        .map(n -> "Result: " + n);71    72    output.ifPresent(System.out::println);73    74    // Safe navigation75    Optional<Integer> price = Optional.of("Product123")76        .flatMap(id -> findProduct(id))77        .map(p -> p.price);78    79    System.out.println("\nProduct price: " + price.orElse(0));80    81}8283static Optional<User> findUser(String id) {84    if (id.equals("123")) {85        return Optional.of(new User("Alice", "alice@example.com"));86    }87    return Optional.empty();88}8990static Optional<Product> findProduct(String id) {91    if (id.equals("Product123")) {92        return Optional.of(new Product("Laptop", 999));93    }94    return Optional.empty();95}9697static class User {98    String name;99    String email;100    User(String nameAlice, String emailalice@example.com) {101        this.name→ Alice = nameAlice;102        this.email→ alice@example.com = emailalice@example.com;103    }
    output
    User: Optional[User(Alice, alice@example.com)]
    All 4 passes — pass 1 is the card above
    passidthis.namethis.emailuseremailnestedflatinputoutputthis.priceprice
    1Alicealice@example.comOptional[User(Alice, alice@example.com)]alice@example.com
    2Alicealice@example.comalice@example.com Optional[alice@example.com]
    3Alicealice@example.comalice@example.comOptional[Optional[User(Alice, alice@example.com)]]
    4Product123Alicealice@example.comalice@example.comOptional[User(Alice, alice@example.com)]Optional[42]Optional[Result: 84]999999 Optional[999]
  5. static Optional<Product> findProduct(String id)

    90static Optional<Product> findProduct(String idProduct123) {91    if (id.equals("Product123")) {
  6. this.name ← Laptop, this.price ← 999, price ← Optional[999]

    74    // Safe navigation75    Optional<Integer> price→ Optional[999] = Optional.of("Product123")76        .flatMap(id -> findProduct(id))77        .map(p -> p.price);78    79    System.out.println("\nProduct price: " + price.orElse(0));80    81}8283static Optional<User> findUser(String id) {84    if (id.equals("123")) {85        return Optional.of(new User("Alice", "alice@example.com"));86    }87    return Optional.empty();88}8990static Optional<Product> findProduct(String id) {91    if (id.equals("Product123")) {92        return Optional.of(new Product("Laptop", 999));93    }94    return Optional.empty();95}9697static class User {98    String name;99    String email;100    User(String name, String email) {101        this.name = name;102        this.email = email;103    }104    public String toString() {105        return "User(" + name + ", " + email + ")";106    }107}108109static class Product {110    String name;111    int price;112    Product(String nameLaptop, int price999) {113        this.name→ Laptop = nameLaptop;114        this.price→ 999 = price999;115    }
    output
    Product price: 999
  1. name ← Optional[bob], upper ← Optional[BOB], length ← Optional[3]

    6public class MapFlatmap {7    public static void main(String[] args) {8        // map - transform value if present9        Optional<String> name→ Optional[bob] = Optional.of("bob");10        11        Optional<String> upper→ Optional[BOB] = name.map(s -> s.toUpperCase());12        System.out.println("Original: " + nameOptional[bob]);13        System.out.println("Uppercase: " + upperOptional[BOB]);14        15        Optional<Integer> length→ Optional[3] = name.map(s -> s.length());16        System.out.println("Length: " + lengthOptional[3]);17        18        // map on empty Optional19        Optional<String> empty→ Optional.empty = Optional.empty();20        Optional<String> result→ Optional.empty = empty.map(s -> s.toUpperCase());21        System.out.println("\nEmpty mapped: " + resultOptional.empty);22        23        24        // Chain multiple maps25        System.out.println("\nChained maps:");26        27        Optional<String> processed→ Optional[HELLO!] = Optional.of("  hello  ")28            .map(s -> s.trim())29            .map(s -> s.toUpperCase())30            .map(s -> s + "!");31        32        System.out.println("Result: " + processed.orElse(""));33        34        // flatMap - when function returns Optional35        Optional<String> userId→ Optional[123] = Optional.of("123");36        37        Optional<User> user = userId.flatMap(id -> findUser(id));38        System.out.println("\nUser: " + user);
    outputOriginal: Optional[bob]
    Uppercase: Optional[BOB]
    Length: Optional[3]
    
    Empty mapped: Optional.empty
    
    Chained maps:
    Result: HELLO!
  2. static Optional<User> findUser(String id)

    pass 1 of 4
    77static Optional<User> findUser(String id123) {78    if (id.equals("123")) {
    All 4 passes — pass 1 is the card above
    passnamethis.namethis.priceprice
    1
    2
    3
    4LaptopLaptop999999 Optional[999]
  3. if (id.equals("123"))

    pass 1 of 4
    77static Optional<User> findUser(String id) {78    if (id.equals("123")) {79        return Optional.of(new User("Alice", "alice@example.com"));80    }
    All 4 passes — pass 1 is the card above
    passidnamethis.namethis.priceprice
    1
    2
    3
    4Product123LaptopLaptop999999 Optional[999]
  4. this.name ← Alice, this.email ← alice@example.com, user ← Optional[User(Alice, alice@example.com)]

    pass 1 of 4
    37    Optional<User> user→ Optional[User(Alice, alice@example.com)] = userId.flatMap(id -> findUser(id));38    System.out.println("\nUser: " + userOptional[User(Alice, alice@example.com)]);39    40    Optional<String> email = userId41        .flatMap(id -> findUser(id))42        .map(u -> u.email);43    System.out.println("Email: " + email);44    45    // map vs flatMap46    System.out.println("\nmap vs flatMap:");47    48    // map wraps result in Optional49    Optional<Optional<User>> nested = userId.map(id -> findUser(id));50    System.out.println("map result: " + nested);51    52    // flatMap doesn't wrap53    Optional<User> flat = userId.flatMap(id -> findUser(id));54    System.out.println("flatMap result: " + flat);55    56    // Practical transformation pipeline57    System.out.println("\nPipeline:");58    59    Optional<String> input = Optional.of("42");60    61    Optional<String> output = input62        .map(s -> Integer.parseInt(s))63        .map(n -> n * 2)64        .map(n -> "Result: " + n);65    66    output.ifPresent(System.out::println);67    68    // Safe navigation69    Optional<Integer> price = Optional.of("Product123")70        .flatMap(id -> findProduct(id))71        .map(p -> p.price);72    73    System.out.println("\nProduct price: " + price.orElse(0));74    75}7677static Optional<User> findUser(String id) {78    if (id.equals("123")) {79        return Optional.of(new User("Alice", "alice@example.com"));80    }81    return Optional.empty();82}8384static Optional<Product> findProduct(String id) {85    if (id.equals("Product123")) {86        return Optional.of(new Product("Laptop", 999));87    }88    return Optional.empty();89}9091static class User {92    String name;93    String email;94    User(String nameAlice, String emailalice@example.com) {95        this.name→ Alice = nameAlice;96        this.email→ alice@example.com = emailalice@example.com;97    }
    output
    User: Optional[User(Alice, alice@example.com)]
    All 4 passes — pass 1 is the card above
    passidthis.namethis.emailuseremailnestedflatinputoutputthis.priceprice
    1Alicealice@example.comOptional[User(Alice, alice@example.com)]alice@example.com
    2Alicealice@example.comalice@example.com Optional[alice@example.com]
    3Alicealice@example.comalice@example.comOptional[Optional[User(Alice, alice@example.com)]]
    4Product123Alicealice@example.comalice@example.comOptional[User(Alice, alice@example.com)]Optional[42]Optional[Result: 84]999999 Optional[999]
  5. static Optional<Product> findProduct(String id)

    84static Optional<Product> findProduct(String idProduct123) {85    if (id.equals("Product123")) {
  6. this.name ← Laptop, this.price ← 999, price ← Optional[999]

    68    // Safe navigation69    Optional<Integer> price→ Optional[999] = Optional.of("Product123")70        .flatMap(id -> findProduct(id))71        .map(p -> p.price);72    73    System.out.println("\nProduct price: " + price.orElse(0));74    75}7677static Optional<User> findUser(String id) {78    if (id.equals("123")) {79        return Optional.of(new User("Alice", "alice@example.com"));80    }81    return Optional.empty();82}8384static Optional<Product> findProduct(String id) {85    if (id.equals("Product123")) {86        return Optional.of(new Product("Laptop", 999));87    }88    return Optional.empty();89}9091static class User {92    String name;93    String email;94    User(String name, String email) {95        this.name = name;96        this.email = email;97    }98    public String toString() {99        return "User(" + name + ", " + email + ")";100    }101}102103static class Product {104    String name;105    int price;106    Product(String nameLaptop, int price999) {107        this.name→ Laptop = nameLaptop;108        this.price→ 999 = price999;109    }
    output
    Product price: 999
  1. name ← Optional.empty, upper ← Optional.empty, length ← Optional.empty

    6public class MapFlatmap {7    public static void main(String[] args) {8        // map - transform value if present9        Optional<String> name→ Optional.empty = Optional.empty();10        11        Optional<String> upper→ Optional.empty = name.map(s -> s.toUpperCase());12        System.out.println("Original: " + nameOptional.empty);13        System.out.println("Uppercase: " + upperOptional.empty);14        15        Optional<Integer> length→ Optional.empty = name.map(s -> s.length());16        System.out.println("Length: " + lengthOptional.empty);17        18        // map on empty Optional19        Optional<String> empty→ Optional.empty = Optional.empty();20        Optional<String> result→ Optional.empty = empty.map(s -> s.toUpperCase());21        System.out.println("\nEmpty mapped: " + resultOptional.empty);22        23        24        // Chain multiple maps25        System.out.println("\nChained maps:");26        27        Optional<String> processed→ Optional[HELLO!] = Optional.of("  hello  ")28            .map(s -> s.trim())29            .map(s -> s.toUpperCase())30            .map(s -> s + "!");31        32        System.out.println("Result: " + processed.orElse(""));33        34        // flatMap - when function returns Optional35        Optional<String> userId→ Optional[123] = Optional.of("123");36        37        Optional<User> user = userId.flatMap(id -> findUser(id));38        System.out.println("\nUser: " + user);
    outputOriginal: Optional.empty
    Uppercase: Optional.empty
    Length: Optional.empty
    
    Empty mapped: Optional.empty
    
    Chained maps:
    Result: HELLO!
  2. static Optional<User> findUser(String id)

    pass 1 of 4
    77static Optional<User> findUser(String id123) {78    if (id.equals("123")) {
    All 4 passes — pass 1 is the card above
    passnamethis.namethis.priceprice
    1
    2
    3
    4LaptopLaptop999999 Optional[999]
  3. if (id.equals("123"))

    pass 1 of 4
    77static Optional<User> findUser(String id) {78    if (id.equals("123")) {79        return Optional.of(new User("Alice", "alice@example.com"));80    }
    All 4 passes — pass 1 is the card above
    passidnamethis.namethis.priceprice
    1
    2
    3
    4Product123LaptopLaptop999999 Optional[999]
  4. this.name ← Alice, this.email ← alice@example.com, user ← Optional[User(Alice, alice@example.com)]

    pass 1 of 4
    37    Optional<User> user→ Optional[User(Alice, alice@example.com)] = userId.flatMap(id -> findUser(id));38    System.out.println("\nUser: " + userOptional[User(Alice, alice@example.com)]);39    40    Optional<String> email = userId41        .flatMap(id -> findUser(id))42        .map(u -> u.email);43    System.out.println("Email: " + email);44    45    // map vs flatMap46    System.out.println("\nmap vs flatMap:");47    48    // map wraps result in Optional49    Optional<Optional<User>> nested = userId.map(id -> findUser(id));50    System.out.println("map result: " + nested);51    52    // flatMap doesn't wrap53    Optional<User> flat = userId.flatMap(id -> findUser(id));54    System.out.println("flatMap result: " + flat);55    56    // Practical transformation pipeline57    System.out.println("\nPipeline:");58    59    Optional<String> input = Optional.of("42");60    61    Optional<String> output = input62        .map(s -> Integer.parseInt(s))63        .map(n -> n * 2)64        .map(n -> "Result: " + n);65    66    output.ifPresent(System.out::println);67    68    // Safe navigation69    Optional<Integer> price = Optional.of("Product123")70        .flatMap(id -> findProduct(id))71        .map(p -> p.price);72    73    System.out.println("\nProduct price: " + price.orElse(0));74    75}7677static Optional<User> findUser(String id) {78    if (id.equals("123")) {79        return Optional.of(new User("Alice", "alice@example.com"));80    }81    return Optional.empty();82}8384static Optional<Product> findProduct(String id) {85    if (id.equals("Product123")) {86        return Optional.of(new Product("Laptop", 999));87    }88    return Optional.empty();89}9091static class User {92    String name;93    String email;94    User(String nameAlice, String emailalice@example.com) {95        this.name→ Alice = nameAlice;96        this.email→ alice@example.com = emailalice@example.com;97    }
    output
    User: Optional[User(Alice, alice@example.com)]
    All 4 passes — pass 1 is the card above
    passidthis.namethis.emailuseremailnestedflatinputoutputthis.priceprice
    1Alicealice@example.comOptional[User(Alice, alice@example.com)]alice@example.com
    2Alicealice@example.comalice@example.com Optional[alice@example.com]
    3Alicealice@example.comalice@example.comOptional[Optional[User(Alice, alice@example.com)]]
    4Product123Alicealice@example.comalice@example.comOptional[User(Alice, alice@example.com)]Optional[42]Optional[Result: 84]999999 Optional[999]
  5. static Optional<Product> findProduct(String id)

    84static Optional<Product> findProduct(String idProduct123) {85    if (id.equals("Product123")) {
  6. this.name ← Laptop, this.price ← 999, price ← Optional[999]

    68    // Safe navigation69    Optional<Integer> price→ Optional[999] = Optional.of("Product123")70        .flatMap(id -> findProduct(id))71        .map(p -> p.price);72    73    System.out.println("\nProduct price: " + price.orElse(0));74    75}7677static Optional<User> findUser(String id) {78    if (id.equals("123")) {79        return Optional.of(new User("Alice", "alice@example.com"));80    }81    return Optional.empty();82}8384static Optional<Product> findProduct(String id) {85    if (id.equals("Product123")) {86        return Optional.of(new Product("Laptop", 999));87    }88    return Optional.empty();89}9091static class User {92    String name;93    String email;94    User(String name, String email) {95        this.name = name;96        this.email = email;97    }98    public String toString() {99        return "User(" + name + ", " + email + ")";100    }101}102103static class Product {104    String name;105    int price;106    Product(String nameLaptop, int price999) {107        this.name→ Laptop = nameLaptop;108        this.price→ 999 = price999;109    }
    output
    Product price: 999

map() transforms value if present. flatMap() for nested Optionals.

map Transform Optional: `opt.map(String::toUpperCase)`. Returns Optional.

Optional return types

Use Optional for methods that might not return a value.

ReturnTypes.java
Replay: real traced execution (multi-file project)
// Optional in return types
// Concept: pattern - using Optional for method returns

import java.util.Optional;
import java.util.HashMap;
import java.util.Map;

public class ReturnTypes {
    // Repository with Optional returns
    static class UserRepository {
        private Map<Integer, User> users = new HashMap<>();

        UserRepository() {
            users.put(1, new User(1, "Alice", "alice@example.com"));
            users.put(2, new User(2, "Bob", "bob@example.com"));
        }

        // Return Optional instead of null
        Optional<User> findById(int id) {
            return Optional.ofNullable(users.get(id));
        }

        Optional<User> findByEmail(String email) {
            return users.values().stream()
                .filter(u -> u.email.equals(email))
                .findFirst();
        }
    }

    static class User {
        int id;
        String name;
        String email;

        User(int id, String name, String email) {
            this.id = id;
            this.name = name;
            this.email = email;
        }

        public String toString() {
            return "User(" + id + ", " + name + ")";
        }
    }

    public static void main(String[] args) {
        UserRepository repo = new UserRepository();

        // Call methods returning Optional
        System.out.println("Finding users:");

        Optional<User> user1 = repo.findById(1);
        user1.ifPresent(u -> System.out.println("  Found: " + u));

        Optional<User> user99 = repo.findById(99);
        user99.ifPresentOrElse(
            u -> System.out.println("  Found: " + u),
            () -> System.out.println("  User 99 not found")
        );


        // Chain Optional operations
        System.out.println("\nChained operations:");

        String userName = repo.findById(1)
            .map(u -> u.name)
            .orElse("Unknown");
        System.out.println("  User 1 name: " + userName);

        String email = repo.findById(99)
            .map(u -> u.email)
            .orElse("no-email@example.com");
        System.out.println("  User 99 email: " + email);

        // Find by email
        System.out.println("\nFind by email:");

        repo.findByEmail("alice@example.com")
            .ifPresent(u -> System.out.println("  Found: " + u));

        repo.findByEmail("unknown@example.com")
            .ifPresent(u -> System.out.println("  Won't print"));

        // Configuration service
        System.out.println("\nConfiguration:");

        ConfigService config = new ConfigService();

        int port = config.getPort().orElse(8080);
        System.out.println("  Port: " + port);

        String host = config.getHost().orElse("localhost");
        System.out.println("  Host: " + host);

        config.getApiKey().ifPresentOrElse(
            key -> System.out.println("  API key: " + key),
            () -> System.out.println("  WARNING: No API key configured")
        );

        // Error handling
        System.out.println("\nWith error handling:");

        try {
            User user = repo.findById(99)
                .orElseThrow(() -> new RuntimeException("User not found"));
        } catch (RuntimeException e) {
            System.out.println("  Error: " + e.getMessage());
        }

        // Transform to different type
        Optional<String> welcomeMsg = repo.findById(2)
            .map(u -> "Welcome, " + u.name + "!");

        System.out.println("\n" + welcomeMsg.orElse("Welcome, Guest!"));
    }

    static class ConfigService {
        Optional<Integer> getPort() {
            return Optional.of(9090);
        }

        Optional<String> getHost() {
            return Optional.empty();  // Not configured
        }

        Optional<String> getApiKey() {
            return Optional.empty();  // Not configured
        }
    }
}
  1. public static void main(String[] args)

    46public static void main(String[] args) {47    UserRepository repo = new UserRepository();
  2. this.id ← 1, this.name ← Alice, this.email ← alice@example.com

    pass 1 of 2
    13    UserRepository() {14        users.put(1, new User(1, "Alice", "alice@example.com"));15        users.put(2, new User(2, "Bob", "bob@example.com"));16    }17    18    // Return Optional instead of null19    Optional<User> findById(int id) {20        return Optional.ofNullable(users.get(id));21    }22    23    Optional<User> findByEmail(String email) {24        return users.values().stream()25            .filter(u -> u.email.equals(email))26            .findFirst();27    }28}2930static class User {31    int id;32    String name;33    String email;34    35    User(int id1, String nameAlice, String emailalice@example.com) {36        this.id→ 1 = id1;37        this.name→ Alice = nameAlice;38        this.email→ alice@example.com = emailalice@example.com;39    }
  3. this.id ← 2, this.name ← Bob, this.email ← bob@example.com

    pass 2 of 2
    14        users.put(1, new User(1, "Alice", "alice@example.com"));15        users.put(2, new User(2, "Bob", "bob@example.com"));16    }17    18    // Return Optional instead of null19    Optional<User> findById(int id) {20        return Optional.ofNullable(users.get(id));21    }22    23    Optional<User> findByEmail(String email) {24        return users.values().stream()25            .filter(u -> u.email.equals(email))26            .findFirst();27    }28}2930static class User {31    int id;32    String name;33    String email;34    35    User(int id2, String nameBob, String emailbob@example.com) {36        this.id→ 2 = id2;37        this.name→ Bob = nameBob;38        this.email→ bob@example.com = emailbob@example.com;39    }
  4. repo ← ⟨ReturnTypes$UserRepository A⟩

    46public static void main(String[] args) {47    UserRepository repo→ ⟨ReturnTypes$UserRepository A⟩ = new UserRepository();48    49    // Call methods returning Optional50    System.out.println("Finding users:");51    52    Optional<User> user1 = repo.findById(1);53    user1.ifPresent(u -> System.out.println("  Found: " + u));
    outputFinding users:
  5. Optional<User> findById(int id)

    pass 1 of 6
    18// Return Optional instead of null19Optional<User> findById(int id1) {20    return Optional.ofNullable(users.get(id1));21}
    All 6 passes — pass 1 is the card above
    passide
    11
    299
    31
    499
    599java.lang.RuntimeException: User not found
    62
  6. user1 ← Optional[User(1, Alice)]

    52Optional<User> user1→ Optional[User(1, Alice)] = repo.findById(1);53user1.ifPresent(u -> System.out.println("  Found: " + u));5455Optional<User> user99 = repo.findById(99);56user99.ifPresentOrElse(
  7. user99 ← Optional.empty

    55Optional<User> user99→ Optional.empty = repo.findById(99);56user99.ifPresentOrElse(57    u -> System.out.println("  Found: " + u),58    () -> System.out.println("  User 99 not found")59);6061//@help h162// Return Optional<T> instead of returning null63// Caller must explicitly handle absence64// Makes API contract clear65//@end6667// Chain Optional operations68System.out.println("\nChained operations:");6970String userName = repo.findById(1)71    .map(u -> u.name)72    .orElse("Unknown");73System.out.println("  User 1 name: " + userName);
    output
    Chained operations:
  8. userName ← Alice

    70String userName→ Alice = repo.findById(1)71    .map(u -> u.name)72    .orElse("Unknown");73System.out.println("  User 1 name: " + userNameAlice);7475String email = repo.findById(99)76    .map(u -> u.email)77    .orElse("no-email@example.com");78System.out.println("  User 99 email: " + email);
    output  User 1 name: Alice
  9. email ← no-email@example.com

    75String email→ no-email@example.com = repo.findById(99)76    .map(u -> u.email)77    .orElse("no-email@example.com");78System.out.println("  User 99 email: " + emailno-email@example.com);7980// Find by email81System.out.println("\nFind by email:");8283repo.findByEmail("alice@example.com")84    .ifPresent(u -> System.out.println("  Found: " + u));
    output  User 99 email: no-email@example.com
    
    Find by email:
  10. Optional<User> findByEmail(String email)

    pass 1 of 2
    23Optional<User> findByEmail(String emailalice@example.com) {24    return users.values().stream()25        .filter(u -> u.email.equals(email))26        .findFirst();27}
  11. repo.findByEmail("alice@example.com")

    83repo.findByEmail("alice@example.com")84    .ifPresent(u -> System.out.println("  Found: " + u));8586repo.findByEmail("unknown@example.com")87    .ifPresent(u -> System.out.println("  Won't print"));
  12. Optional<User> findByEmail(String email)

    pass 2 of 2
    23Optional<User> findByEmail(String emailunknown@example.com) {24    return users.values().stream()25        .filter(u -> u.email.equals(email))26        .findFirst();27}
  13. config ← ⟨ReturnTypes$ConfigService B⟩

    86repo.findByEmail("unknown@example.com")87    .ifPresent(u -> System.out.println("  Won't print"));8889// Configuration service90System.out.println("\nConfiguration:");9192ConfigService config→ ⟨ReturnTypes$ConfigService B⟩ = new ConfigService();9394int port = config.getPort().orElse(8080);95System.out.println("  Port: " + port);
    output
    Configuration:
  14. port ← 9090

    94int port→ 9090 = config.getPort().orElse(8080);95System.out.println("  Port: " + port9090);9697String host = config.getHost().orElse("localhost");98System.out.println("  Host: " + host);
    output  Port: 9090
  15. host ← localhost

    97String host→ localhost = config.getHost().orElse("localhost");98System.out.println("  Host: " + hostlocalhost);99100config.getApiKey().ifPresentOrElse(101    key -> System.out.println("  API key: " + key),102    () -> System.out.println("  WARNING: No API key configured")103);
    output  Host: localhost
  16. config.getApiKey().ifPresentOrElse(

    100config.getApiKey().ifPresentOrElse(101    key -> System.out.println("  API key: " + key),102    () -> System.out.println("  WARNING: No API key configured")103);104105// Error handling106System.out.println("\nWith error handling:");
    output
    With error handling:
  17. catch (RuntimeException e)

    110        .orElseThrow(() -> new RuntimeException("User not found"));111} catch (RuntimeException ejava.lang.RuntimeException: User not found) {112    System.out.println("  Error: " + e.getMessage());113}
    output  Error: User not found
  18. Optional<String> welcomeMsg = repo.findById(2)

    115// Transform to different type116Optional<String> welcomeMsg = repo.findById(2)117    .map(u -> "Welcome, " + u.name + "!");
  19. welcomeMsg ← Optional[Welcome, Bob!]

    115    // Transform to different type116    Optional<String> welcomeMsg→ Optional[Welcome, Bob!] = repo.findById(2)117        .map(u -> "Welcome, " + u.name + "!");118    119    System.out.println("\n" + welcomeMsg.orElse("Welcome, Guest!"));120}
    output
    Welcome, Bob!

Return Optional<T> instead of nullable T. Caller knows to check.

Exercise: Practical.java

Refactor a service layer to use Optional