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.

Java 9 Features – Private Interface Methods

java, java 9, technology

Duke-Java9

A blog on Java 9 changes for interfaces.

Evolution of interfaces in Java:

Until Java 7, all versions of Java maintained the same set of features for interfaces. Interfaces can

Interfaces contained method signatures and were useful for storing public constants. Since then, constants have remained a staple of the interface. Recent changes have been more focused on methods.

Java 7

  • abstract methods – Method signatures as contracts that had to be implemented by the class that implemented the interface.

Java 8

  • default methods – Methods with an implementation in the interface, providing an option to the implementing class to override.

    This change allowed for extension and growth of existing APIs without major refactoring and without harming backward-compatibility. Best example of this is the Java 8 collection framework that introduced new features on the root interfaces without having to make significant changes to any of the implementations.

    See http://docs.oracle.com/javase/8/docs/api/java/util/List.html for sort(...) or spliterator() or replaceAll(...).

  • static methods – Methods with the static modifier with an implementation, which thus belong to the interface.

    These methods cannot be overwritten in implementing classes. Adding static methods allows the interface to control some behavior without allowing for an implementation to alter such behavior.

    See http://docs.oracle.com/javase/8/docs/api/java/util/Map.Entry.html for comparingByKey() or comparingByValue().

Java 9

  • private methods – Methods with implementation in the interface that remain private to the interface alone.

    These methods are useful from an encapsulation perspective to hold some logic that the implementations should not override.

    While there is no concrete example in the JDK API that I could immediately find, there are several existing interfaces which have workarounds for encapsulating private methods via private inner classes. Such workarounds can be circumvented with private methods.

Java support in interfaces

  Java 7 Java 8 Java 9
constants
abstract methods
default methods
public static methods
private methods
private static methods

Modifier combinations in Java 9

Combination Comment
[public] (naturally abstract) supported
[public] default supported
[public] static supported
private supported
private static supported
private abstract compile-time error
private default compile-time error