/ / Expressões lambda recursivas no Java 8 - java, lambda, java-8

Expressões lambda recursivas no Java 8 - java, lambda, java-8

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 № 1

Você 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));
}
}

Relacionado: Por que os lambdas em Java 8 não permitem referências futuras a variáveis ​​de membros em que classes anônimas não fazem isso?