Box and Maybe Summary
Box Concept
- Generic container for a single value
- Provides abstraction barrier
- Enables functional operations
- Example:
class Box<T> { private final T item; private Box(T item) { this.item = item; } public static <T> Box<T> of(T item) { return new Box<>(item); } }
Maybe Concept
- Represents optional values
- Handles null cases safely
- Two variants: Some and None
- Example:
abstract class Maybe<T> { private Maybe() { } public static <T> Maybe<T> some(T value) { return new Some<>(value); } public static <T> Maybe<T> none() { return new None<>(); } }
Map and FlatMap
- Map transforms content
- FlatMap handles nested containers
- Example:
// Map example Maybe<String> name = Maybe.some("hello"); Maybe<Integer> length = name.map(s -> s.length()); // FlatMap example Maybe<Maybe<String>> nested = Maybe.some(Maybe.some("hello")); Maybe<String> flattened = nested.flatMap(x -> x);
Null Safety
- Avoids NullPointerException
- Makes null checks explicit
- Example:
// Instead of: String s = getStringMaybeNull(); if (s != null) { System.out.println(s.length()); } // Using Maybe: Maybe<String> s = getStringMaybe(); s.map(str -> str.length()) .ifPresent(System.out::println);
Functional Operations
- filter: Conditionally keep values
- map: Transform values
- flatMap: Handle nested Maybes
- Example:
Maybe<Integer> result = Maybe.some(42) .filter(x -> x > 0) .map(x -> x * 2) .flatMap(x -> Maybe.some(x + 1));
Best Practices
- Use Maybe for optional values
- Chain operations functionally
- Avoid null checks
- Handle both Some and None cases
- Document Maybe usage
- Consider performance implications