Java 8 – Lambdas

Lambdas und Methodenreferenzen in Java 8

Lambda-Ausdrücke und Methoden-/Konstruktorreferenzen unterstützen seit Java 8 einen funktionalen Programmierstil. In anderen Programmiersprachen sind Lambdas als Closures bekannt.

Der Begriff Lambda-Ausdruck stammt vom Lambda-Kalkül, einer formalen Sprache zur Definition und Anwendung von Funktionen und gebundenen Parametern, die bereits in den 1930er Jahren beschrieben wurde.

Lambda-Ausdrücke

Durch eine Erweiterung des Iterable-Interface haben Collections in Java 8 eine forEach-Methode, welche die bekannte for…each-Schleife ersetzen kann. Die Schleife im folgenden Code

lässt sich jetzt auch so schreiben:

An die forEach-Methode der Collection wird ein Lambda-Ausdruck übergeben, der aus Parameterliste und Rumpf besteht, durch „->“ getrennt.

Die Lambda-Parameterliste enthält Definitionen für das oder die zu verarbeitenden Elemente der Collection. Sie kann Angaben zum Parametertyp enthalten, dieser kann aber auch automatisch vom Compiler (und von der IDE) bestimmt werden. Mehrere Parameter werden in runden Klammern durch Komma separiert angegeben. Im Beispiel wird i als Variable für das Listenelement definiert, der Typ Integer wird automatisch erkannt.

Der Lambda-Rumpf ist ein einzelner Ausdruck oder eine Liste von Anweisungen in geschweiften Klammern. Er definiert, welche Funktionen auf das oder die Elemente angewendet werden sollen. Im Beispiel wird das Element auf die Konsole ausgegeben.

Der Compiler erkennt, wenn die Typen der Parameter nicht zu der angegebenen Funktion passen:

Man kann den Parametertypen explizit angegeben, falls er nicht aus dem Kontext geschlossen werden kann:

Einen Lambda-Ausdruck kann man auch über eine Variable referenzieren und damit als Parameter an eine Methode übergeben:

Methoden- und Konstruktorreferenzen

Wenn in einem Lambda-Rumpf nur eine Methode aufgerufen wird, kann man den Lambda-Ausdruck häufig durch eine einfache Methodenreferenz ersetzen. Das ist erlaubt, wenn der Compiler Typ und Anzahl der Parameter für die Methodenreferenz automatisch bestimmen kann. Der oben genannte Lambda-Ausdruck lässt sich als Methodenreferenz so schreiben:

Die Methodenreferenz besteht aus einem Receiver und Methodennamen, durch „::“ getrennt. Wenn der Receiver ein Objekt ist, muss der Methodenname eine existierende nicht-statische Methode sein. Wenn der Receiver ein Typ ist, muss der Methodenname eine statische Methode oder der Ausdruck new für den Konstruktor sein.

Im Beispiel schließt der Compiler aus dem Kontext, dass an die referenzierte Methode ein Parameter vom Typ Integer (oder int) übergeben werden muss. Dazu muss es im System.out-Objekt eine zum Typ Integer passende Überladung der Methode println geben.

Definiert als Variable sehen Methoden- und Konstruktorreferenzen so aus:

Ausblick

Die hier vorgestellten Lambda-Ausdrücke und Methodenreferenzen spielen eine große Rolle bei der Nutzung von Streams für die Verarbeitung und den Zugriff auf Collections. Das Stream API wird in einem weiteren Beitrag vorgestellt.

Quelle: Java Magazin 12 | 2013

Verfasst von Marion Wilker am 4. Oktober 2016