我倾向于在Scala中编程并遇到这个问题,其中Scala代码抛出StackOverflowErorr,而Java中的类似实现可以在抛出相同的错误之前更多一点
def recursiveSum(args: Int*): Int = {
if (args.length == 0) 0
else
args.head + recursiveSum(args.tail: _*)
}
recursiveSum(5000 to 15000: _*)
Run Code Online (Sandbox Code Playgroud)
我得到的错误是
java.lang.StackOverflowError
//| at scala.collection.Parallelizable$class.$init$(Parallelizable.scala:20)
//| at scala.collection.AbstractTraversable.<init>(Traversable.scala:105)
//| at scala.collection.AbstractIterable.<init>(Iterable.scala:54)
//| at scala.collection.AbstractSeq.<init>(Seq.scala:40)
//| at scala.collection.immutable.Range.<init>(Range.scala:44)
//| at scala.collection.immutable.Range$Inclusive.<init>(Range.scala:330)
//| at scala.collection.immutable.Range$Inclusive.copy(Range.scala:333)
//| at scala.collection.immutable.Range.drop(Range.scala:170)
//| at scala.collection.immutable.Range.tail(Range.scala:196)
//| at scala.collection.immutable.Range.tail(Range.scala:44)
//| at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//| at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//| at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//| at Loops$$anonfun$main$1.recursiveSum$1(Loops.scala:11)
//| at Loops$$anonfun$m
//| Output exceeds cutoff limit.
Run Code Online (Sandbox Code Playgroud)
java代码是
static int recursiveSum(int... arg) {
if (arg.length == 0)
return 0;
else
return arg[0] + recursiveSum(Arrays.copyOfRange(arg, 1, arg.length));
}
public static void main(String[] args) {
System.out.println(recursiveSum(range(5000, 15000)));
}
private static int[] range(int i, int j) {
int list[] = new int[j - i + 1];
int idx = 0;
for (int s = i; s <= j; s++)
list[idx++] = s;
return list;
}
Run Code Online (Sandbox Code Playgroud)
为什么Scala的尾递归优化没有帮助?Java如何处理(Java无法处理超过15000个16000)?
它们在台式机上以相同的eclipse运行,默认堆栈大小为java 7.
这不是尾递归.为了使函数成为尾递归,函数中的最后一个语句(尾部)需要是递归调用.在你的情况下,它可能看起来像,但如果你用注释注释你的函数@tailrec,你会发现它不是.实际上,你的最后一个语句是一个补充,而不是递归调用.
如果你重写你的函数使用累加器,你将能够做一个尾递归版本...
def recursiveSum(args: Int*): Int = {
@tailrec
def sumAccumulator(sum: Int, args: Int*): Int = {
if(args.length == 0) sum
else sumAccumulator(sum + args.head, args.tail: _*)
}
sumAccumulator(0, args: _*)
}
recursiveSum(5000 to 15000: _*)
Run Code Online (Sandbox Code Playgroud)