Java 堆栈和递归
The Java stack and recursion
我的问题是关于 Java 堆栈的设计。它是在设计时考虑了递归,还是由于堆栈的结构而导致递归?
一个明显的非答案:
实际上,带递归的 "real thing" 是 tail recursion,编译器认识到这一点,并在幕后将其优化为迭代循环。
令人惊讶的是:Java 无法做到这一点。因此,在现实世界中,递归和 Java 并不能很好地结合在一起。几千次递归调用可能会使您的 JVM 崩溃。所以你绝对要尽量避免真正的递归java。对于孤立的小问题来说,这是一件很巧妙的事情。但除此之外,递归是 "not" Java.
中的一件事
而stack的设计大概更多的是基于20年前为虚拟机打造一个简单易移植系统的想法。这两个概念(堆栈和递归)在 Java v1 发布之前就已经存在。
Java8 添加了 lambda 表达式和功能接口,如下所述: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 = …
请在link中查看更多详细信息:https://www.scala-exercises.org/scala_tutorial/tail_recursion
我的问题是关于 Java 堆栈的设计。它是在设计时考虑了递归,还是由于堆栈的结构而导致递归?
一个明显的非答案:
实际上,带递归的 "real thing" 是 tail recursion,编译器认识到这一点,并在幕后将其优化为迭代循环。
令人惊讶的是:Java 无法做到这一点。因此,在现实世界中,递归和 Java 并不能很好地结合在一起。几千次递归调用可能会使您的 JVM 崩溃。所以你绝对要尽量避免真正的递归java。对于孤立的小问题来说,这是一件很巧妙的事情。但除此之外,递归是 "not" Java.
中的一件事而stack的设计大概更多的是基于20年前为虚拟机打造一个简单易移植系统的想法。这两个概念(堆栈和递归)在 Java v1 发布之前就已经存在。
Java8 添加了 lambda 表达式和功能接口,如下所述: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 = …
请在link中查看更多详细信息:https://www.scala-exercises.org/scala_tutorial/tail_recursion