Eu só queria definir uma expressão lambda Java 8 recursivamente.
o FAQ do Lambda menciona que é possível definir uma expressão lambda recursiva somente durante a inicialização de campo (estático).
Mas eu recebo um erro de compilador no IntelliJ (o javac apenas relata um erro sem uma mensagem):
java: auto-referência no inicializador
Se eu tentar escrever algo como:
static UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * f.apply( i - 1);
ou
UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * f.apply( i - 1);
Uma maneira que encontrei para fazer funcionar foi usar uma matriz para referenciar o lambda efetivamente enganando o compilador java:
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));
}
}
Existe outro truque para definir a expressão lambda recursiva?
Respostas:
8 para resposta № 1Você pode fazê-lo ao qualificar totalmente o nome do campo que você está referenciando recursivamente. Esta versão compila sem nenhum erro:
import java.util.function.UnaryOperator;
public class RecursiveLambdaExample {
static UnaryOperator<Integer> fac = i -> i == 0 ? 1 : i * RecursiveLambdaExample.fac.apply( i - 1);
UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * this.f.apply( i - 1);
public static void main(String[] args) {
System.out.println(new RecursiveLambdaExample().f.apply(5));
System.out.println(fac.apply(5));
}
}