Java8 使用 lambda 表达式理解尾递归函数:

Java8 Understanding tail-recursive function using a lambda expression:

我正在尝试 lambda Java8 lambda 表达式,其中我遇到了这个例子。我无法理解程序流程,

下例调用factorialTailRec(1, 5).invoke()语句时程序流程如下:

  1. 程序首先进入factorialTailRec方法并检查一次number值是否等于1。在第一次迭代中,不是,因此进入else部分。

  2. 在 else 块中,流程被重定向到 TailCall class 内的 call 方法,它将 return 相同的对象。

  3. 现在调用 invoke 方法,然后 Stream 对象尝试遍历结果。我不知道如何再次调用 factorialTailRec?他们说是因为下面的声明,

    TailCall::apply
    

但是,我不明白这是怎么回事。?

public class Factorial {
  

  public static TailCall<Integer> factorialTailRec(
    final int factorial, final int number) {      
    if (number == 1)
      return done(factorial);
    else
      return call(() -> factorialTailRec(factorial * number, number - 1));
  }

  public static int factorial(final int number) {
    return factorialTailRec(1, number).invoke();
  }

  public static void main(final String[] args) {
   
    System.out.println("//" + "START:FACTTAILREC_DISPLAY_5_OUTPUT");
    System.out.println(factorialTailRec(1, 5).invoke());
    System.out.println("//" + "END:FACTTAILREC_DISPLAY_5_OUTPUT");

   
  }
}


@FunctionalInterface
public interface TailCall<T> {
  
  TailCall<T> apply();
  
  default boolean isComplete() { return false; }
  //...

  default T result() { throw new Error("not implemented"); }
  
  default T invoke() {
    return Stream.iterate(this, TailCall::apply)
                 .filter(TailCall::isComplete)
                 .findFirst()
                 .get()
                 .result();
  }
}

public class TailCalls {
  public static <T> TailCall<T> call(final TailCall<T> nextCall) {
    return nextCall;
  }
  public static <T> TailCall<T> done(final T value) {
    return new TailCall<T>() {      
      @Override public boolean isComplete() { return true; }
      @Override public T result() { return value; }
      @Override public TailCall<T> apply() { 
        throw new Error("not implemented"); 
      }
    };
  }  
}

下面的代码

else
  return call(() -> factorialTailRec(factorial * number, number - 1));

等同于

else {
  TailCall<Integer> nextCall = new TailCall<Integer>() {
    @Override
    public TailCall<Integer> apply() {
      return factorialTailRec(factorial * number, number - 1);
    }
  };
  return call(nextCall);
}

在 else 块中,创建了一个新的 TailCall 对象,其 apply 函数返回另一个 TailCall 对象。 (参见 FunctionalInterface

一个完整的调用链是:factorialTailRec(1, 5) -> factorialTailRec(5, 4) -> factorialTailRec(20, 3) -> factorialTailRec(60, 2) -> factorialTailRec(120, 1) -> done(120).