Optional

Optional #

The class Optional was introduced in Java 8. An Optional is a container object that may or may not contain a value. Its main purpose is to indicate that the object returned by a function may be null.

Example. In our game, the interface Board provides a method getUnit(int rowIndex, int columnIndex), that returns the unit standing on the tile with these coordinates, if any.

This could be implemented with a method

$\qquad$ Unit getUnit(int rowIndex, int columnIndex)

that returns null if there is no unit on this tile (and returns the unit otherwise).

However, from the signature of this method, it is not immediately clear that the returned unit may be null. This may cause a NullPointerException at runtime, if the method is called by some program that does not check whether this unit is null.

Instead, we can use

$\qquad$ Optional<Unit> getUnit(int rowIndex, columnIndex)

to clearly indicate that the return value may not be present.

Syntax #

Declaring an empty Optional #

An empty Optional can be initialized with the static method Optional.empty().

Example.

Optional<Unit> unit = Optional.empty();

Setting an Optional’s value #

The value of an Optional can be set with the static method Optional.of.

Example.

Optional<Unit> unicorn = Optional.of(new Unicorn("green"));

Getting an Optional’s value #

Whether an Optional has a value can be checked with the instance method Optional.isPresent(), and the value (if present) can be retrieved with the instance method Optional.get().

Example.

Optional<Unit> unit = board.getUnit(rowIndex, columnIndex);
if(unit.isPresent()){
    unit.get().boost();
}

The instance method Optional.ifPresent can be used (as an alternative) for the same purpose.

If the optional object has type Optional<$T$>, then ifPresent takes as argument a callback method with type

$\qquad T \to$ void

(a.k.a. a Java Consumer) that is executed iff the Optional is nonempty.

Example.

Optional<Unit> unit = board.getUnit(rowIndex, columnIndex);
unit.ifPresent(u -> u.boost());

Primitive types #

Java 8 also introduced the container OptionalInt (resp. OptionalLong, OptionalDouble), which behaves analogously to Optional<Integer> (resp. Optional<Long>, Optional<Double>), but contains an int (resp. long, double). It is mostly used in combination with IntStream (resp. LongStream, DoubleStream).

Optional and streams #

Some methods of the interface Stream<$T$> (resp. IntStream, LongStream, DoubleStream) return an Optional<$T$> (resp.OptionalInt, OptionalLong, OptionalDouble).

In particular:

  • findFirst
  • average,
  • max and min
  • etc.