The java.util.Optional<T>
class is a container object that may or may not contain a non-null value. It was introduced in Java 8 as part of the Java language’s growing emphasis on treating null values as an anti-pattern. Optional
is a way of replacing a nullable T
reference with a non-null but potentially empty Optional<T>
reference.
In functional terminology, Optional
is a monadic sequence of operations that can be combined to work with data in a declarative way, while deferring some operations, such as computations on elements.
Here are some useful methods that Optional class provides:
Optional.of(T value)
: Returns anOptional
with the specified present non-null value.Optional.empty()
: Returns an emptyOptional
instance.Optional.ofNullable(T value)
: Returns anOptional
describing the specified value, if non-null, otherwise returns an emptyOptional
.get()
: If a value is present in thisOptional
, returns the value, otherwise throwsNoSuchElementException
.isPresent()
: Returnstrue
if there is a value present, otherwisefalse
.ifPresent(Consumer<? super T> consumer)
: If a value is present, invokes the specified consumer with the value, otherwise does nothing.orElse(T other)
: Returns the value if present, otherwise returns other.orElseGet(Supplier<? extends T> other)
: Returns the value if present, otherwise returns the result produced by the supplying function.orElseThrow(Supplier<? extends X> exceptionSupplier)
: If a value is present, returns the value, otherwise throws an exception produced by the exception supplying function.
In practical terms, using Optional
can help make your code more robust and reduce the likelihood of NullPointerException
.
Here is a simple example:
package org.kodejava.util;
import java.util.Optional;
public class OptionalIntroduction {
public static void main(String[] args) {
Optional<String> opt = Optional.of("Hello, world!");
if (opt.isPresent()) {
System.out.println(opt.get());
}
}
}
This program will output: Hello, world!
We can utilize functional-style programming by using ifPresent()
method provided by the Optional
class. Here’s how:
package org.kodejava.util;
import java.util.Optional;
public class OptionalIfPresent {
public static void main(String[] args) {
Optional<String> opt = Optional.of("Hello, world!");
opt.ifPresent(System.out::println);
}
}
In this example, opt.ifPresent(System.out::println);
is used to print the value of opt
if it is present. The System.out::println
syntax is a method reference in Java 8 that is functionally equivalent to value -> System.out.println(value)
. It will only execute System.out.println()
if opt
is not empty. Hence, it can be considered functional-style programming.
Here are another code snippet on using other methods from the java.util.Optional
class:
package org.kodejava.util;
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
// Creating Optional objects
// 1. Creates an empty Optional
Optional<String> empty = Optional.empty();
// 2. Creates an Optional with a non-null value
Optional<String> nonEmpty = Optional.of("Hello");
// 3. Creates an Optional with a null value
Optional<String> nullable = Optional.ofNullable(null);
// isPresent()
// 1. Output: true
System.out.println(nonEmpty.isPresent());
// 2. Output: false
System.out.println(empty.isPresent());
// ifPresent()
// 1. Output: Value is present: Hello
nonEmpty.ifPresent(value -> System.out.println("Value is present: " + value));
// 2. No output, since the Optional is empty.
empty.ifPresent(value -> System.out.println("Value is present: " + value));
// orElse()
String valueFromNonEmpty = nonEmpty.orElse("Default Value");
String valueFromEmpty = empty.orElse("Default Value");
// Output: Hello
System.out.println(valueFromNonEmpty);
// Output: Default Value
System.out.println(valueFromEmpty);
// orElseGet()
String valueFromNonEmptyWithSupplier = nonEmpty.orElseGet(() -> "Default Value");
String valueFromEmptyWithSupplier = empty.orElseGet(() -> "Default Value");
// Output: Hello
System.out.println(valueFromNonEmptyWithSupplier);
// Output: Default Value
System.out.println(valueFromEmptyWithSupplier);
// orElseThrow() when value is present it will return the value
try {
String value = nonEmpty.orElseThrow(IllegalArgumentException::new);
System.out.println(value);
} catch (IllegalArgumentException e) {
//Handle exception
e.printStackTrace();
}
// orElseThrow() when value is not present, it throws an exception
try {
String value = empty.orElseThrow(IllegalArgumentException::new);
System.out.println(value);
} catch (IllegalArgumentException e) {
//Handle exception
e.printStackTrace();
}
}
}
Output:
true
false
Value is present: Hello
Hello
Default Value
Hello
Default Value
Hello
java.lang.IllegalArgumentException
at java.base/java.util.Optional.orElseThrow(Optional.java:403)
at org.kodejava.util.OptionalExample.main(OptionalExample.java:53)
These methods are used to help in providing a more elegant way to handle null
values in Java. Make sure to understand how and when to use each method to get the most out of the Optional
class.