© Excellent backgrounds/Shutterstock.com
Java Magazin
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 fort. Wir haben dieses Thema bereits in unserem Artikel über Kollektoren [1] kurz angeschnitten. Diesmal wollen wir ins Detail gehen.

Angelika Langer, Klaus Kreft


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 zum JDK dazugekommen, sondern auch ihre primitiven Geschwisterklassen OptionalInt, OptionalLong und OptionalDouble. Wir werden uns in dem Artikel aber auf Optional 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 reduce(BinaryOperator accumulator)

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

T reduce(T identity, BinaryOperator 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 einfach zu interpretieren. Es könnte ja so sein, dass der Stream leer ist und wir einfach nur den Anfangswert 0 wieder zurückbekommen, ohne dass es überhaupt zur Addition kommt. Dies ist zum Beispiel hier der Fall:

int sum = Str...

Java Magazin
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 fort. Wir haben dieses Thema bereits in unserem Artikel über Kollektoren [1] kurz angeschnitten. Diesmal wollen wir ins Detail gehen.

Angelika Langer, Klaus Kreft


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 zum JDK dazugekommen, sondern auch ihre primitiven Geschwisterklassen OptionalInt, OptionalLong und OptionalDouble. Wir werden uns in dem Artikel aber auf Optional 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 reduce(BinaryOperator accumulator)

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

T reduce(T identity, BinaryOperator 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 einfach zu interpretieren. Es könnte ja so sein, dass der Stream leer ist und wir einfach nur den Anfangswert 0 wieder zurückbekommen, ohne dass es überhaupt zur Addition kommt. Dies ist zum Beispiel hier der Fall:

int sum = Str...

Neugierig geworden?


    
Loading...

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