![]() | |
|
A java.util.Optional<T>
object is either a wrapper for an Object
of type
T
or a wrapper for no object. It is intended as a safer alternative than a reference of
type T
that refers to an Object
or null
.
Following is the declaration for java.util.Optional<T>
class:
public final class Optional<T> extends Object { ... }
Creating Optional objects
The first step before working with Optional
is to learn how to create optional objects. There are
several ways:
Empty Optional
You can get hold of an empty optional object using the static factory method
Optional.empty()
:
Optional<String> str = Optional.empty();
Optional
from a non-null value
You can also create an optional from a non-null value with the static
factory method
Optional.of(...)
:
String str = "ABC"; Optional<String> optStr = Optional.of(str);
![]() | |
If |
Optional
from null
able value
Finally, by using the static
factory method Optional.ofNullable(...)
, you can
create an Optional
object that may hold a null
value:
String str = null; Optional<String> optStr = Optional.ofNullable(str);
In the example above, since the str
is null
, the resulting
Optional
object would be empty.
The ofNullable(...)
method is intended as a bridge from the use of null
values to optional values. The Optional.ofNullable(obj)
returns
Optional.of(obj)
if obj
is not null
, and
Optional.empty()
otherwise.
Unwrapping an Optional
The Optional
class provides several instance methods to read the value contained
by an Optional
instance.
Optional.get()
- is the simplest but also the least safe of these methods. It returns
the wrapped value if present but throws a NoSuchElementException
otherwise. For this
reason, using this method is almost always a bad idea unless you are really sure the optional
contains a value.
Optional.orElse(T other)
it allows you to provide a default value for when the optional
does not contain a value.
NOTE: the other
value may be null
.
Optional.orElseGet(Supplier<? extends T> other)
is the lazy counterpart of the
orElse
method, because the supplier is invoked only if the optional contains no
value. You should use this method either when the default value is time-consuming to create
or you want to be sure this is done only if the optional is empty.
<X extends Throwable> Optional.orElseThrow(Supplier<? extends X> exceptionSupplier)
is similar to
the get()
method in that it throws an exception when the optional is empty, but in
this case it allows you to choose the type of exception that you want to throw.
Optional.ifPresent(Consumer<? super T> consumer)
lets you execute the action
given as argument if a value is present; otherwise no action is taken.
Optional.isPresent()
returns true
if the Optional
contains
a value, false
otherwise.
Optional.isEmpty()
returns true
if the Optional
is empty,
false
otherwise.
Converting an Optional
into a Stream
The Optional.stream()
method allows you to convert an Optional
to a Stream
.
If the Optional
contains a value, it will return a Stream
containing only that
value, otherwise, it will return an empty Stream
:
Optional<Integer> in = Optional.of(1); in.stream() .filter(i -> i > 0) .forEach(System.out::println);
1
The Optional.stream()
method can be helpful when you are dealing with a stream of
Optional
elements. It will help to filter out empty optionals and keep the ones
with values.
Assume we have a list of optionals received from a method, and some of the optionals are empty:
Stream<Optional<String>> stream = Stream.of( Optional.of("Java"), Optional.empty(), Optional.of("is"), Optional.empty(), Optional.of("good"));
In Java 8.0 you could remove empty optionals as follows:
List<String> list = stream .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty()) .collect(Collectors.toList());
In Java 9.0 and later you can remove empty optionals with shorter code using flatMap()
:
List<String> list = stream .flatMap(Optional::stream) .collect(Collectors.toList());
The map()
and flatMap()
in Optional
![]() | |
Both
Use |
If the function returns the exact type we need:
Optional<String> s = Optional.of("Java"); s = s.map(String::toUpperCase); // function returns String s.ifPresent(System.out::print);
If we have a function that returns an Optional
then using map()
would lead
to a nested structure of optionals, as the map()
does an additional wrapping. Use
flatMap()
to keep a flat structure:
Optional<String> s = Optional.of("Java"); s = s.flatMap(val -> Optional.of(val.toUpperCase())); // function returns Optional<String> s.ifPresent(System.out::print);
![]() ![]() ![]() |