这是什么原因为*异常?
import java.math.BigInteger;
import java.util.HashMap;
/**
*
* @author cypronmaya
*/
public class test {
static HashMap<Integer, BigInteger> cache = new HashMap<Integer, BigInteger>();
public static void main(String[] args) {
System.out.println(factorial(20000));
}
public static BigInteger factorial(int n) {
BigInteger ret;
if (n == 0) {
return BigInteger.ONE;
}
if (null != (ret = cache.get(n))) {
return ret;
}
ret = BigInteger.valueOf(n).multiply(factorial(n - 1));
cache.put(n, ret);
return ret;
}
}
在 java.util.HashMap.get(来源不明)异常线程 “main” java.lang.*Error的这是什么原因为*异常?
嗨, 为什么我收到计算器例外程序?
我知道,*通常意味着你有一个无限循环, ,但这工作正常,当我使用10000或其他数字较小,突然无限大数字?
A *Error
发生在调用堆栈溢出时。当你有太多的嵌套调用时(这是因为每个调用都需要在堆栈上保留空间,并且它的大小是有限的)。我想你的情况,20000是太多了。
您可以用-Xss
标志修改JVM的堆栈大小。但我建议你找到一种不同的方法来计算阶乘。
同意这一点。修改堆栈大小是你可以做的事情,但不是这种类型的问题。 @cypronmaya你应该寻找另一种编程阶乘的方式。 – 2012-02-05 12:29:34
我认为使用缓存会加快进一步调用因子 – cypronmaya 2012-02-05 12:48:57
@oli charlesworth你能建议一个因子计划,它可以计算更高的数字并且还有缓存(用于使事情进一步因子调用更快) – cypronmaya 2012-02-05 12:51:28
递归函数每次调用创建堆栈中的一个新的指针,因此有大量的递归函数就可以得到的*异常的通话时间...
提示:更换用循环来递归函数来解决。
原因是你的阶乘函数是递归的,这不是tail recursion。
这意味着每次调用“factorial”函数时,都会将此调用放入堆栈。
我不知道Java编译器是否可以生成尾递归调用,但如果可以的话,您可以简单地将函数重构为尾调用方式。否则,只要避免递归(无论如何都是命令式语言的一个好习惯)。
Java编译器或JVM(JIT编译器)尚未(尚未)优化尾部调用。也许在未来的版本中。 – Jesper 2012-02-05 12:44:23
非递归版本(不像编译 - 这是堆栈溢出)。将有更清晰的方式来写这个。
public class Test {
private static final Object lock = new Object();
private static final List<BigInteger> cache = new ArrayList<>(
Arrays.asList(BigInteger.ONE)
);
public static void main(String[] args) {
System.out.println(factorial(20000));
}
public static BigInteger factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
synchronized (lock) {
int r = cache.size();
if (n < r) {
return cache.get(n);
}
BigInteger current = cache.get(r-1);
for (;;) {
current = BigInteger.valueOf(r).multiply(current);
cache.add(current);
if (n == r) {
return current;
}
++r;
}
}
}
}
,您可以调整默认的Java堆栈大小运行与-Xss switch
eg: java -Xss2048k YourClass
你可以计算阶乘'(10000)''然后阶乘(20000)'。 ;)(这个代码是线程敌对的,顺便说一句,对于负数'n'有点奇怪。) – 2012-02-05 12:36:49