Lambda-Ausdrücke können auf sich selbst verweisen, doch da ein this zur Selbstreferenz nicht möglich ist, ist ein kleiner Umweg nötig. Erstes muss eine Objekt- oder Klassenvariable deklariert werden, zweitens dann dieser Variablen ein Lambda-Ausdruck zugewiesen werden und dann kann drittens dieser Lambda-Ausdruck auf diese Variable zugreifen und einen rekursiven Aufruf starten. Für den Klassiker der Fakultät sieht das so aus:
public class RecursiveFactLambda {
public static IntFunction<Integer> fact = n -> (n == 0) ? 1 : n * fact.apply(n-1);
public static void main( String[] args ) {
System.out.println( fact.apply( 5 ) ); // 120
}
}
IntFunction ist eine funktionale Schnittstelle mit den der Operation T apply(int i), und T ist ein generischer Rückgabetyp, den wir hier mit Integer belegt haben.
fact hätte genauso gut als normale Methode deklariert werden können – großartige Vorteile bietet die Schreibweise mit Lambda-Ausdrücken nicht. Zumal jetzt auch der Begriff „anonyme Funktion“ nicht mehr so richtig schlüssig ist, da der Lambda-Ausdruck ja doch einen Namen hat, nämlich fact.
Lieber Herr Ullenboom,
ich habeversucht das Beispiel zu dem Thema Rekursive Lambda-Ausdrücke auszuführen, doch das dortige fact im else-Bereich des Bedienungsoperators wird rot unterstrichen!
Ich bekomme angezeigt: Cannot reference a field before it is defined.
Woran könnte das liegen?
MFG Marius
Hi Marius,
statt
public static IntFunction fact = n -> (n == 0) ? 1 : n * fact.apply(n – 1);
schreib mal
public static IntFunction fact = n -> (n == 0) ? 1 : n * RecursiveFactLambda.fact.apply(n – 1);
Also den Klassennamen und einen Punkt vor den Lambda-Funktionsaufruf schreiben.
Damit bekommt man die von Dir beschriebene Fehlermeldung weg (die ich hier nachvollziehen konnte).
(Es kann mit der Java Version zusammenhängen. Ich verwende das Java 8 Beta: 1.8.0_25-b18)
Schöne Grüße und weiterhin viel Spaß mit Lambdas!
Hartmut
Dankeschön, jetzt funktioniert es!