I just wanted to define a Java 8 lambda expression recursively.
The Lambda FAQ mentions that one can define a recursive lambda expression only during (static) field initialization.
But I get a compiler error in IntelliJ (javac just reports an error without a message):
java: self-reference in initializer
If I try to write something like:
static UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * f.apply( i - 1);
or
UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * f.apply( i - 1);
One way I found to make it work was to use an array for referencing the lambda effectively tricks the java compiler:
import java.util.function.UnaryOperator;
public class RecursiveLambdaExample {
public static void main(String[] args) {
UnaryOperator<Integer>[] fac = new UnaryOperator[1];
fac[0] = i -> i == 0 ? 1 : i * fac[0].apply( i - 1);
UnaryOperator<Integer> factorial = fac[0];
System.out.println(factorial.apply(5));
}
}
Is there another trick to define recursive lambda expression?
You are able to achieve this with nested class:
output:
You can make it work by fully-qualifying the field name that you're referencing recursively. This version compiles without any error:
Related: Why do lambdas in Java 8 disallow forward reference to member variables where anonymous classes don't?