Java8 使用 lambda 表达式理解尾递归函数:
Java8 Understanding tail-recursive function using a lambda expression:
我正在尝试 lambda Java8 lambda 表达式,其中我遇到了这个例子。我无法理解程序流程,
下例调用factorialTailRec(1, 5).invoke()语句时程序流程如下:
程序首先进入factorialTailRec方法并检查一次number值是否等于1。在第一次迭代中,不是,因此进入else部分。
在 else 块中,流程被重定向到 TailCall class 内的 call 方法,它将 return 相同的对象。
现在调用 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)
.
我正在尝试 lambda Java8 lambda 表达式,其中我遇到了这个例子。我无法理解程序流程,
下例调用factorialTailRec(1, 5).invoke()语句时程序流程如下:
程序首先进入factorialTailRec方法并检查一次number值是否等于1。在第一次迭代中,不是,因此进入else部分。
在 else 块中,流程被重定向到 TailCall class 内的 call 方法,它将 return 相同的对象。
现在调用 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)
.