Optional<T> class final

A container object which may or may not contain a non-null value.

If a value is present, isPresent returns true. If no value is present, the object is considered empty and isPresent returns false.

Additional methods that depend on the presence or absence of a contained value are provided, such as orElse (returns a default value if no value is present) and ifPresent (performs an action if a value is present).

Usage Examples

Basic Creation and Checking

// Create an Optional with a value
Optional<String> name = Optional.of("John");
print(name.isPresent()); // true
print(name.get()); // "John"

// Create an empty Optional
Optional<String> empty = Optional.empty();
print(empty.isPresent()); // false
print(empty.isEmpty()); // true

// Create Optional from nullable value
String? nullableValue = null;
Optional<String> fromNullable = Optional.ofNullable(nullableValue);
print(fromNullable.isEmpty()); // true

Safe Value Retrieval

Optional<String> name = Optional.of("Alice");
Optional<String> empty = Optional.empty();

// Using orElse for default values
print(name.orElse("Unknown")); // "Alice"
print(empty.orElse("Unknown")); // "Unknown"

// Using orElseGet with a supplier function
print(empty.orElseGet(() => "Generated default")); // "Generated default"

// Using orElseThrow
try {
  print(empty.orElseThrow(() => Exception("No value present")));
} catch (e) {
  print("Caught: $e"); // Caught: Exception: No value present
}

Conditional Operations

Optional<String> name = Optional.of("Bob");
Optional<String> empty = Optional.empty();

// Execute action if value is present
name.ifPresent((value) => print("Hello, $value!")); // Hello, Bob!
empty.ifPresent((value) => print("This won't print"));

// Execute different actions based on presence
name.ifPresentOrElse(
  (value) => print("Found: $value"), // This executes
  () => print("No value found")
);

empty.ifPresentOrElse(
  (value) => print("Found: $value"),
  () => print("No value found") // This executes
);

Transformations and Filtering

Optional<String> name = Optional.of("john doe");

// Transform the value if present
Optional<String> upperName = name.map((s) => s.toUpperCase());
print(upperName.get()); // "JOHN DOE"

// Chain transformations
Optional<int> nameLength = name
    .map((s) => s.replaceAll(" ", ""))
    .map((s) => s.length);
print(nameLength.get()); // 7

// Filter based on condition
Optional<String> longName = name.filter((s) => s.length > 5);
print(longName.isPresent()); // true

Optional<String> shortName = name.filter((s) => s.length < 5);
print(shortName.isEmpty()); // true

// FlatMap for nested Optionals
Optional<String> parseNumber(String s) {
  try {
    int.parse(s);
    return Optional.of(s);
  } catch (e) {
    return Optional.empty();
  }
}

Optional<String> input = Optional.of("123");
Optional<String> validNumber = input.flatMap(parseNumber);
print(validNumber.isPresent()); // true

Working with Collections

List<Optional<String>> optionals = [
  Optional.of("apple"),
  Optional.empty(),
  Optional.of("banana"),
  Optional.empty(),
  Optional.of("cherry")
];

// Filter out empty optionals and get values
List<String> fruits = optionals
    .where((opt) => opt.isPresent())
    .map((opt) => opt.get())
    .toList();
print(fruits); // [apple, banana, cherry]

// Using stream() method for functional processing
List<String> upperFruits = optionals
    .expand((opt) => opt.stream())
    .map((fruit) => fruit.toUpperCase())
    .toList();
print(upperFruits); // [APPLE, BANANA, CHERRY]

Error Handling Patterns

// Safe division function
Optional<double> safeDivide(double a, double b) {
  return b != 0 ? Optional.of(a / b) : Optional.empty();
}

// Usage with error handling
Optional<double> result = safeDivide(10, 2);
result.ifPresentOrElse(
  (value) => print("Result: $value"), // Result: 5.0
  () => print("Division by zero!")
);

// Chain operations safely
Optional<String> formatResult = safeDivide(15, 3)
    .filter((value) => value > 1)
    .map((value) => "Result: ${value.toStringAsFixed(2)}");

print(formatResult.orElse("No valid result")); // Result: 5.00

API Note

Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors. A variable whose type is Optional should never itself be null; it should always point to an Optional instance.

Annotations

Properties

hashCode int
Returns the hash code of the value, if present, otherwise 0 (zero) if no value is present.
no setteroverride
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

filter([bool predicate(T)?]) Optional<T>
If a value is present, and the value matches the given predicate, returns an Optional describing the value, otherwise returns an empty Optional.
flatMap<U>([Optional<U> mapper(T)?]) Optional<U>
If a value is present, returns the result of applying the given Optional-bearing mapping function to the value, otherwise returns an empty Optional.
get() → T
If a value is present, returns the value, otherwise throws InvalidArgumentException.
ifPresent([void action(T)?]) → void
If a value is present, performs the given action with the value, otherwise does nothing.
ifPresentOrElse([void action(T)?, void emptyAction()?]) → void
If a value is present, performs the given action with the value, otherwise performs the given empty-based action.
isEmpty() bool
If a value is not present, returns true, otherwise false.
isPresent() bool
If a value is present, returns true, otherwise false.
map<U>([U? mapper(T)?]) Optional<U>
If a value is present, returns an Optional describing (as if by ofNullable) the result of applying the given mapping function to the value, otherwise returns an empty Optional.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
or([Optional<T> supplier()?]) Optional<T>
If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function.
orElse(T? other) → T?
If a value is present, returns the value, otherwise returns other.
orElseGet([T supplier()?]) → T
If a value is present, returns the value, otherwise returns the result produced by the supplying function.
orElseThrow() → T
If a value is present, returns the value, otherwise throws InvalidArgumentException.
orElseThrowWith<X extends Object>([X exceptionSupplier()?]) → T
If a value is present, returns the value, otherwise throws an exception produced by the exception supplying function.
stream() Iterable<T>
If a value is present, returns an Iterable containing only that value, otherwise returns an empty Iterable.
toString() String
Returns a non-empty string representation of this Optional suitable for debugging.
override

Operators

operator ==(Object other) bool
Indicates whether some other object is "equal to" this Optional.
override

Static Methods

empty<T>() Optional<T>
Returns an empty Optional instance. No value is present for this Optional.
of<T>(T value) Optional<T>
Returns an Optional describing the given non-null value.
ofNullable<T>(T? value) Optional<T>
Returns an Optional describing the given value, if non-null, otherwise returns an empty Optional.