Java 8中的递归lambda表达式

时间:2014-08-11 21:46:55

标签: java lambda java-8

我只是想以递归方式定义Java 8 lambda表达式。

Lambda FAQ提到只能在(静态)字段初始化期间定义递归lambda表达式。

但我在IntelliJ中遇到编译器错误(javac只报告没有消息的错误):

  

java:初始化程序中的自引用

如果我尝试写下这样的话:

static UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * f.apply( i - 1);

UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * f.apply( i - 1);

我发现使其工作的一种方法是使用数组来引用lambda有效地欺骗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));
    }
}

还有另一个定义递归lambda表达式的技巧吗?

2 个答案:

答案 0 :(得分:9)

您可以通过完全限定递归引用的字段名称来使其工作。此版本编译时没有任何错误:

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

相关:Why do lambdas in Java 8 disallow forward reference to member variables where anonymous classes don't?

答案 1 :(得分:2)

您可以使用嵌套类来实现:

public class Main {

    public static void main(String[] args) {

        class Helper {
            final UnaryOperator<Integer> f = i -> i == 0 ? 1 : i * this.f.apply( i - 1);
        }

       System.out.println(new Helper().f.apply(3));
    }
}

输出:

6