在Java 1.8里,如何用Lambda实现递归? - 小巫师的专栏 - CSDN博客

用阶乘函数 n! = n * (n-1)! 作为例子:

@FunctionalInterface

static interface IntFunc {

int apply(`int n);`

}

public static void main(String[] args) {

IntFunc factor = n -> n <= 0 ? 1 : n * factor.apply(n - 1`);`

System.out.println(factor.apply(`10`)); // Expect: 3628800

}

其实这段代码是无法编译通过的。那么如何才能用Lambda实现递归呢?

修改一下:

public static void main(String[] args) {

IntFunc[] factor = new IntFunc[`1`];

factor[`0] = n -> n <=` `0` `?` `1` `: n * factor[0].apply(n -` `1);`

System.out.println(factor[`0].apply(10`)); // Expect: 3628800

}

这段代码是可以跑的,但Lambda里用到了外边的变量,实际上没有真正把函数“匿名”起来。

再看这段,连接口形式都改掉了:

@FunctionalInterface

static interface SelfIntFunc {

int apply(SelfIntFunc self, int n);

}

public static void main(String[] args) {

SelfIntFunc factor = (self, n) -> n <= 0 ? 1 : n * self.apply(self, n - 1`);`

System.out.println(factor.apply(factor, 10`)); // Expect: 3628800`

}

多传一个self的参数,就可以自己引用自己了。

但是有没有觉得不爽?首先要多传一个参数,其次仍旧需要对Lambda给个名字(还是没有真正“匿名”起来),如果连名字都不能有,就只能写成这样了:

public static void main(String[] args) {

System.out.println(((SelfIntFunc) (self, n) -> n <= 0 ? 1 : n * self.apply(self, n - 1`)).apply((self, n) -> n <= 0 ? 1 : n * self.apply(self, n - 1),` `10)); // Expect: 3628800`

}

Lambda被重复了2次,多啰嗦啊。不过也好办,引入一个“构造函数”:

static IntFunc build(SelfIntFunc self) {

return n -> self.apply(self, n);

}

public static void main(String[] args) {

System.out.println(build((self, n) -> n <= 0 ? 1 : n * self.apply(self, n - 1`)).apply(10)); // Expect: 3628800`

}

这样就彻底“匿名”了。

那么,能不能把“构造函数”也“匿名”呢?很简单:

public static void main(String[] args) {

System.out.println(((Function<SelfIntFunc, IntFunc>) self -> n -> self.apply(self, n)).apply((self, n) -> n <= 0 ? 1 : n * self.apply(self, n - 1`)).apply(10)); // Expect: 3628800`

}

看明白了没有?

参考:

用JavaScript做的Lambda试验:http://blog.csdn.net/g9yuayon/article/details/1271319

Lambda和图灵的停机问题:http://mindhacks.cn/2006/10/15/cantor-godel-turing-an-eternal-golden-diagonal/


Original url: Access
Created at: 2019-11-22 12:46:58
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论