Java8 добавил лямбда-выражение и функциональный интерфейс, как описано здесь: https://blog.knoldus.com/tail-recursion-in-java-8/
, который позволяет нам определить наш собственный хвостовой рекурсивный интерфейс:
@FunctionalInterface
public interface TailCall {
TailCall 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 Factorial{
public static TailCall factorialTailRec(final int factorial, final int number) {
if (number == 1)
return TailCalls.done(factorial);
else
return call(() -> factorialTailRec(factorial * number, number - 1));
}
}
однако, Java изначально не имеет в виду никакой хвостовой рекурсивной оптимизации. По сравнению со Scala (я думаю, лучше Java), Scala имеет аннотацию @tailrec
, поэтому компилятор будет оптимизировать рекурсию нерекурсивным способом, если эта подсказка предоставлена и с учетом того, что функция является истинной функцией tailrec.
@tailrec
def gcd(a: Int, b: Int): Int = …
см. Более подробную информацию по этой ссылке: https://www.scala -exercises.org / scala_tutorial / tail_recursion