Java 9 Features – Changes to Optional

java, java 9, technology

Duke-Java9

In Java 8, a new class named Optional was introduced. Or rather in the word-style of Douglas Adams, “in the beginning null was created. This made a lot of people angry and was widely regarded as a bad move“. Optional was introduced to alleviate some of that anger.

Optional relieved developers of the grief of null checks and the “fun” of a NullPointerException popping up when failing to null check.

In Java 8, the Optional already had very useful methods:

  • of – Wrap the non-null value into an Optional.
  • ofNullable – Wrap and return an Optional of the current value, if current value is null, return Optional.empty()
  • isPresent – Checks and returns a boolean indicating the presence of a non-null value in the Optional.
  • ifPresent – Checks and invokes the specified Consumer instance upon the presence of a non-null value in the Optional.
  • get – Fetch the value in the Optional if it is not null, else throw a NoSuchElementException
  • orElse – Fetch the value in the Optional if it is not null, else return the other element passed in.
  • orElseGet – Fetch the value in the Optional if it is not null, else return invoke the other Supplier to fetch an element instead.
  • orElseThrow – Fetch the value in the Optional if it is not null, else throw the passed in Exception.
  • filter – If the value exists, test the filtering Predicate on it and if true return result wrapped in an Optional, else return Optional.empty().
  • map – If the value exists, apply the mapping Function to it and return any non-null result wrapped in an Optional, else return Optional.empty().
  • flatMap – If the value exists, apply the Optional-bearing mapping Function to it and return any non-null result wrapped in an Optional, else return Optional.empty().

Java 9 changes

  • ifPresentOrElse – Checks and returns a boolean indicating the presence of a non-null value in the Optional, or else, invokes the Runnable action.
  • or – Wrap and return an Optional of the current value if not null; if current value is null, return Optional by invoking the specified Supplier
  • stream – Returns a sequential stream containing only the value, if the value is non-null.

Optional::ifPresentOrElse

Consider a situation where the code is to either run a Consumer if the value exists or else run a different action. This is not possible in the Java 8 Optional behavior. Optional in Java 8 provides an orElse or an orElseGet method, both of which actually return an unwrapped value, rather than act as an execution block.

Source at: https://github.com/c-guntur/java9-examples/blob/master/src/test/java/samples/java9/optional/OptionalIfPresentOrElse.java

Pre-Java 8 :


if(preference != null) { 
    callPresenceAction();
} else {
    callAbsenceAction();
}

In Java 8 :


if(optionalPreference.isPresent()) { 
    callPresenceAction();
} else {
    callAbsenceAction();
}

or


optionalPreference.ifPresent(callPresenceConsumer());
// orElseGet returns a non-optional value
// it cannot be used to simply execute an action.
Preference p = optionalPreference.orElseGet(callAbsenceSupplier());

In Java 9 :


optionalPreference
        .ifPresentOrElse(presenceAction,absenceAction);

Optional::or

Per the Java 8 API, both the orElse and the orElseGet do not return an Optional, rather return the unwrapped value. It is possible that such a value is null. The or method is introduced as a means to execute a supplier on absence of an unwrapped value in the container, and returns an Optional, rather than the unwrapped value.

Source at: https://github.com/c-guntur/java9-examples/blob/master/src/test/java/samples/java9/optional/OptionalOr.java

Pre-Java 8 :


Preference preference = findPreference(name); 
if(preference == null) {
    preference = createPreference(name, description);
}
// preference can still be null !!!

In Java 8 :


Preference preference = 
        findOptionalPreference(name)
            .orElseGet(getPreferenceSupplier(name, description));
// preference can still be null !!!

In Java 9 :


Optional<Preference> optionalPreference = 
        findOptionalPreference(name)
            .or(getOptionalPreferenceSupplier(name, description));
// optional preference, so, protected from being null !!!

Optional::stream

Given a situation where a stream or collection of Optionals exist, and we need to extract values from each, if they contain non-null values. Optional::stream returns a stream with a single non-null value if the Optional has a non-null value, or returns an empty stream otherwise.

Source at: https://github.com/c-guntur/java9-examples/blob/master/src/test/java/samples/java9/optional/OptionalStream.java

Pre-Java 8 :


List preferences = new ArrayList();
for (String preferenceName : PREFERENCE_NAMES) {
    Preference aPreference = findPreference(preferenceName);
    if (aPreference != null) {
        preferences.add(aPreference);
    }
}

In Java 8 :


List preferences =
        PREFERENCE_NAMES.stream()
                .map(preferenceName -> findOptionalPreference(preferenceName))
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(toList());

In Java 9 :


List preferences =
        PREFERENCE_NAMES.stream()
                .map(preferenceName -> findOptionalPreference(preferenceName))
                .flatMap(Optional::stream)
                .collect(toList());

That’s a wrap on the Optional changes in Java 9. Hope this post was helpful.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s