首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java8实现递归lambda函数

用Java8实现递归lambda函数
EN

Stack Overflow用户
提问于 2013-10-17 22:34:43
回答 24查看 35.4K关注 0票数 66

Java 8引入了lambda函数,我想实现像factorial这样的东西:

代码语言:javascript
复制
 IntToDoubleFunction fact = x -> x == 0 ? 1 : x * fact.applyAsDouble(x-1);

编译返回

代码语言:javascript
复制
  error: variable fact might not have been initialized

我如何引用函数本身。类是匿名的,但实例是存在的:它被称为fact

EN

回答 24

Stack Overflow用户

发布于 2014-08-25 00:35:10

我通常使用(一次性定义的函数接口)泛型助手类,它包装了函数接口类型的变量。这种方法解决了局部变量初始化的问题,并使代码看起来更清晰。

在这个问题中,代码将如下所示:

代码语言:javascript
复制
// Recursive.java
// @param <I> - Functional Interface Type
public class Recursive<I> {
    public I func;
}

// Test.java
public double factorial(int n) {

    Recursive<IntToDoubleFunction> recursive = new Recursive<>();
    recursive.func = x -> (x == 0) ? 1 : x * recursive.func.applyAsDouble(x - 1);

    return recursive.func.applyAsDouble(n);
}
票数 51
EN

Stack Overflow用户

发布于 2014-04-09 13:11:26

一种方法是编写第二个函数helper,该函数接受一个函数和一个数字作为参数,然后编写您真正想要的函数fact = helper(helper,x)

如下所示:

代码语言:javascript
复制
BiFunction<BiFunction, Double, Double> factHelper =
        (f, x) -> (x == 0) ? 1.0 : x*(double)f.apply(f,x-1);
Function<Double, Double> fact =
        x -> factHelper.apply(factHelper, x);

在我看来,这似乎比依赖角例语义(如捕获对可变结构的引用的闭包)或允许自我引用并警告“可能无法初始化”要稍微优雅一些。

但是,由于Java的类型系统,这并不是一个完美的解决方案--泛型不能保证factHelper的参数ffactHelper的类型相同(即相同的输入类型和输出类型),因为这将是一个无限嵌套的泛型。

因此,更安全的解决方案可能是:

代码语言:javascript
复制
Function<Double, Double> fact = x -> {
    BiFunction<BiFunction, Double, Double> factHelper =
        (f, d) -> (d == 0) ? 1.0 : d*(double)f.apply(f,d-1);
    return factHelper.apply(factHelper, x);
};

factHelper不太完美的泛型类型引起的代码味道现在被包含(或者,我敢说,被封装)在lambda中,确保factHelper永远不会被无意中调用。

票数 21
EN

Stack Overflow用户

发布于 2013-10-18 17:18:27

本地类和匿名类,以及lambda,在创建本地变量时通过值来捕获它们。因此,它们不可能通过捕获局部变量来引用它们自己,因为在创建它们的时候,指向它们自己的值还不存在。

本地类和匿名类中的代码仍然可以使用this引用自身。但是,lambda中的this并不引用lambda;它引用来自外部作用域的this

您可以捕获一个可变的数据结构,如数组:

代码语言:javascript
复制
IntToDoubleFunction[] foo = { null };
foo[0] = x -> { return  ( x == 0)?1:x* foo[0].applyAsDouble(x-1);};

尽管这算不上是一个优雅的解决方案。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19429667

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档