of<T> static method
Returns an Optional describing the given non-null value.
value
the value to describe, which must be non-null
Returns an Optional with the value present.
Throws InvalidArgumentException if value is null.
Example
Optional<String> name = Optional.of("Alice");
print(name.get()); // "Alice"
// This will throw an InvalidArgumentException
try {
Optional<String> invalid = Optional.of(null);
} catch (e) {
print("Error: $e"); // Error: Invalid argument(s): value cannot be null
}
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.
Implementation
static Optional<T> of<T>(T value) {
if (value == null) {
throw InvalidArgumentException('value cannot be null');
}
return Optional<T>._(value);
}