加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

这段Recursive lambda如何在Java中调用

发布时间:2020-12-15 00:53:58 所属栏目:Java 来源:网络整理
导读:我最近在 Java中遇到了这段代码.它涉及功能和印刷斐波那契数字,它的工作原理. public class AppLambdaSubstitution {public static FunctionInteger,Integer Y(FunctionFunctionInteger,Integer,FunctionInteger,Integer f) { return x - f.apply(Y(f)).appl
我最近在 Java中遇到了这段代码.它涉及功能和印刷斐波那契数字,它的工作原理.
public class AppLambdaSubstitution {

public static Function<Integer,Integer> Y(Function<Function<Integer,Integer>,Function<Integer,Integer>> f) {
    return x -> f.apply(Y(f)).apply(x);
}

public static void main(String[] args) {
    Function<Integer,Integer> fib = Y(
            func -> x -> {
        if (x < 2)
            return x;
        else
            return func.apply(x - 1) + func.apply(x - 2);
    });

    IntStream.range(1,11).
    mapToObj(Integer::valueOf).
    map(fib).forEach(System.out::println);
  }
}

令我困惑的部分是返回x – > f.apply(Y(F)).适用(X);.是不是Y(f)是对方法Y的递归调用?我们一直用函数f作为参数来调用它.对我来说,这种递归调用没有基本情况.为什么无休止的递归调用没有溢出?

解决方法

从根本上说,你错过了x – >的观点. .f.apply(Y(f))的应用(X);不会调用apply,它会返回一个Function.

这只是一种非常复杂(并且非直观?)的方式来显示IMO的currying和递归函数.如果要替换一些东西并使其更具可读性,事情就会简单得多.

这种结构:

Function<Function<Integer,Integer>>

根本不需要,因为根本没有使用左参数.只需要掌握正确的一个.因此左边的参数可以是任何东西(我稍后会用供应商替换它 – 也不需要,但只是为了证明一点).

实际上你在这里关心的是这个函数,它为Stream的每个元素进行实际计算:

public static Function<Integer,Integer> right() {

    return new Function<Integer,Integer>() {
        @Override
        public Integer apply(Integer x) {
            if (x < 2) {
                return x;
            } else {
                return apply(x - 1) + apply(x - 2);
            }
        }
    };
}

现在你可以用以下内容编写整个构造:

Supplier<Function<Integer,Integer>> toUse = () -> right();
 Function<Integer,Integer> fib = curry(toUse);
 IntStream.range(1,11)
          .mapToObj(Integer::valueOf)
          .map(fib)
          .forEach(System.out::println);

该供应商<功能<整数,整数>> toUse =() – >对();应该让你理解为什么在前面的例子中(函数< Function,Function>)需要左边部分 – 只是为了得到正确的一部分.

如果您看得更近,您可能会注意到完全不需要供应商,因此您甚至可以通过以下方式进一步简化:

IntStream.range(1,11)
         .mapToObj(Integer::valueOf)
         .map(right())
         .forEach(System.out::println);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读