这段Recursive lambda如何在Java中调用

前端之家收集整理的这篇文章主要介绍了这段Recursive lambda如何在Java中调用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我最近在 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);
原文链接:https://www.f2er.com/java/130011.html

猜你在找的Java相关文章