簡體   English   中英

Java 8 中的遞歸 lambda 表達式

[英]Recursive lambda expressions in 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 表達式?

您可以通過完全限定您遞歸引用的字段名稱來使其工作。 這個版本編譯沒有任何錯誤:

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

相關:為什么 Java 8 中的 lambda 不允許前向引用匿名類不允許的成員變量?

您可以使用嵌套類來實現這一點:

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

只需將您的 lambda 擴展為匿名類:

    UnaryOperator<Integer> f = new UnaryOperator<Integer>(){
        @Override
        public Integer apply(Integer i) {
            return i == 0 ? 1 : i * this.apply( i - 1);
        }
    };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM