我正在编写一个可以自我调用约5000次的函数。当然,我得到一个StackOverflowError
。有什么方法可以用相当简单的方式重写这段代码吗?:
void checkBlocks(Block b, int amm) {
//Stuff that might issue a return call
Block blockDown = (Block) b.getRelative(BlockFace.DOWN);
if (condition)
checkBlocks(blockDown, amm);
Block blockUp = (Block) b.getRelative(BlockFace.UP);
if (condition)
checkBlocks(blockUp, amm);
//Same code 4 more times for each side
}
顺便说一句,我们可以称之为功能的深度有多大限制?
答案 0 :(得分:19)
使用显式堆栈对象和循环,而不是调用堆栈和递归:
void checkBlocks(Block b, int amm) {
Stack<Block> blocks = new Stack<Block>();
blocks.push(b);
while (!blocks.isEmpty()) {
b = blocks.pop();
Block blockDown = (Block) b.getRelative(BlockFace.DOWN);
if (condition)
blocks.push(block);
Block blockUp = (Block) b.getRelative(BlockFace.UP);
if (condition)
blocks.push(block);
}
}
答案 1 :(得分:6)
java中的默认堆栈大小为512kb。如果超过该程序将终止抛出StackOverflowException
您可以通过传递JVM参数来增加堆栈大小: -Xss1024k
现在堆栈大小为1024kb。您可以根据您的环境提供更高的价值
我认为我们不能以编程方式更改此
答案 2 :(得分:0)
您可以使用-Xss4m增加堆栈大小。
答案 3 :(得分:0)
只要块可用,您就可以将“块”放入队列/堆栈中并进行迭代。
答案 4 :(得分:0)
很明显,你的StackOverflow具有递归的分支因子。在其他语言中,可以实现by Tail Call Optimization。但我想你的问题需要另一种方法来解决。
理想情况下,您会对Block执行一些检查。也许你可以获得所有块的列表并迭代地检查每个块?
答案 5 :(得分:0)
在大多数情况下,递归以错误的方式使用。您不应该获得堆栈溢出异常。 您的方法没有返回类型/值。 你如何确保你的初始Block b有效?
如果您正在使用递归,请回答以下问题:
示例:
我的递归锚点是n == 2(结果是2),所以我可以计算从这个锚点开始的所有结果。
我的递归步骤是n-1(所以每一步我都接近解决方案(在这个事实中我的递归锚))