Skip to content

Latest commit

 

History

History
108 lines (74 loc) · 3.41 KB

Optional.md

File metadata and controls

108 lines (74 loc) · 3.41 KB
tree_title description last_modified
Optional type
How and when to use the Java Optional type
2020-05-30 15:54:15 +0200

Optional type (Java)

Contents

Basic idea

Optional<T>: a wrapper for either an object of type T or no object

Goal: provide safer alternative to returning either an object of type T or null

Main use case: return type for methods that do not necessarily produce a value

Note: Method parameters of type Optional are not recommended because this makes it awkward to call the method. For implementing methods with optional parameters, method overloading is generally considered a better option. See also Why should Java 8's Optional not be used in arguments

How to use Optional values

Basically, two sensible options:

  • use a method that produces an alternative value if the Optional is empty
  • use a method that only consumes the value if the Optional is not empty

Examples first option:

String result = optionalString.orElse("");
String result = optionalString.orElseGet(functionReturningString);
String result = optionalString.orElseThrow(IllegalStateException::new);

Examples second option:

optionalString.ifPresent(processString); // returns nothing

optionalString.ifPresentOrElse(
        System.out::println, 
        () -> System.out.println("Empty!")); // returns nothing

// Optional containing the length of the value (if it was present) and empty otherwise
optionalString.map(String::length)
    
optionalString.flatMap(functionReturningOptionalInteger) // Optional<Integer>

How not to use Optional values

When used in the wrong way, using Optional is not safer or easier than using null

Examples:

nullableString.length() // length throws NullPointerException
optionalString.get().length() // get throws NoSuchElementException

if (nullableString != null) {
    length = nullableString.length()
}

if (optionalString.isPresent()) {
    length = optionalString.get().length()
}

Creating Optional values

Optional<String> optionalString = Optional.of("test"); // throws if argument null
Optional<String> optionalString = Optional.ofNullable(nullableString);
Optional<String> optionalString = Optional.empty();

Turning an Optional into a Stream

Conceptually, you can compare an Optional to a stream with either zero or one elements. The .stream() method follows that principle, yielding a stream with zero elements if the Optional is empty and a stream with one element if the optional has a value

Example use case:

idsStream
        .map(Users::lookup) // Users.lookUp returns an Optional<User>
        .flatMap(Optional::stream)

Note: if you call a method that returns either a value or null, you can apply the samle principle using Stream.ofNullable:

idsStream
        .map(Users::lookup) // Users.lookUp returns a User object or null
        .flatMap(Stream::ofNullable)

Resources