© Excellent backgrounds/Shutterstock.com
Effective Java - Teil 11

Java 8: Optional


Wir setzen unsere Reihe zum Thema Java-8-Neuerungen in diesem Heft mit der Klasse java.util.Optional<T> fort. Wir haben dieses Thema bereits in unserem Artikel über ­Kollektoren [1] kurz angeschnitten. Diesmal wollen wir ins Detail gehen.

Optional ist eine Abstraktion, die in Java 8 zum JDK hinzugekommen ist und von einigen Streamoperationen als Returntyp verwendet wird. Ein Optional kann einen Wert enthalten oder aber leer sein, daher der Name: Der Wert ist optional. Da die Entwicklung der Optional-Klasse von kontroversen Diskussionen begleitet wurde, sowohl im OpenJDK-Forum [2] wie auch außerhalb [3], wollen wir sie näher betrachten.

Genau genommen ist nicht nur die Klasse Optional<T> zum JDK dazugekommen, sondern auch ihre primitiven Geschwisterklassen OptionalInt, OptionalLong und OptionalDouble. Wir werden uns in dem Artikel aber auf Optional<T> konzentrieren, da die anderen Klassen nur Varianten für die primitiven Typen int, long und double sind. Alles Gesagte gilt so oder so ähnlich auch für die primitiven Optional-Klassen. Wo es Abweichungen gibt, werden wir diese erwähnen. Beginnen wir damit, wie Optional im JDK benutzt wird.

Optional und Streams

Optional wird im JDK-API von einigen wenigen Stream­operationen als Returntyp genutzt. Ein Beispiel dafür ist die Streamoperation:

Optional<T> reduce(BinaryOperator<T> accumulator)

Warum gibt reduce() hier ein Optional<T> zurück? Zumal es auch eine überladene Version von reduce() gibt, die kein Optional<T>, sondern ein T zurückgibt:

T reduce(T identity, BinaryOperator<T> accumulator)

Was macht den Unterschied? Schauen wir uns das an einem Beispiel an. Zunächst die Version, die T zurückgibt:

int sum = Stream.of(-2, -1, 0, 1, 2) .reduce(0, (i, j) -> i + j); System.out.println("sum is: " + sum);

Diese Version funktioniert so, dass ihr als erster Parameter ein Anfangswert und als zweiter Parameter die reduce-Funktionalität übergeben wird. Das Javadoc fordert, dass der Anfangswert bezüglich der reduce-Funktionalität das neutrale Element sein muss. Das ist bei uns der Fall: Der Anfangswert ist 0, die reduce-Funktionalität ist die Integer-Addition, und offensichtlich liefert die Addition mit 0 immer den Ausgangswert. Lässt man das Beispiel ablaufen, ist seine Ausgabe wie folgt:

sum is: 0

Das ist nicht besonders überraschend. Wenn wir uns die Stream-Elemente ansehen, so können wir feststellen, dass sich diese in der Tat zu 0 addieren. Falls man die Stream-Elemente aber nicht kennt, ist das Ergebnis 0 nicht so ...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang