You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何增大java.util.Stack实例的默认容量?

问题分析与解决方案

首先得澄清一个关键误解:你遇到的StackOverflowError大概率不是Stack容器的容量不够导致的,而是递归调用过深触发了Java虚拟机的调用栈溢出——这是两个完全不同的概念。

先回答你关于Stack容量的问题:

  • Stack继承自Vector,而Vector本身是会自动扩容的:默认初始容量是10,当元素数量超过当前容量时,它会自动把容量扩容为原来的2倍(你也可以通过ensureCapacity(int minCapacity)方法提前指定最小容量)。比如你可以在初始化destinations的时候调用:
    this.destinations.ensureCapacity(20);
    
    这个方法会确保Stack的底层容量至少达到20,不会像setSize()那样添加null元素,只是提前完成扩容操作,避免后续自动扩容的性能开销。
  • 另外,Vector永远不会因为容量不足抛出StackOverflowError,最多只会在内存耗尽时抛出OutOfMemoryError,所以你遇到的错误肯定不是容器容量的问题。

你的代码问题:递归调用导致的调用栈溢出

看你的代码逻辑,每次传送失败时,你会把当前目标加入栈,然后递归调用sendTransporterToHuman处理新的目标;传送成功后,又会递归弹出栈里的目标处理。这种递归方式如果遇到连续多次失败的情况,递归深度会不断累积,一旦超过JVM的默认调用栈深度(通常在几百到几千之间,取决于JVM参数),就会抛出StackOverflowError。

解决这个问题的最佳方式是把递归改成迭代,用循环来处理栈里的目标,避免调用栈被耗尽:

private void sendTransporterToHuman(Coord initialDest) {
    Coord currentDest = initialDest;
    while (true) {
        boolean successfulJourney = sendTransporterTo(currentDest, HUMAN);
        if (successfulJourney) {
            if (this.destinations.isEmpty()) {
                break;
            } else {
                currentDest = this.destinations.pop();
            }
        } else {
            this.destinations.add(currentDest);
            currentDest = new Coord(currentDest.X() - 1, currentDest.Y());
        }
    }
}

这个迭代版本的逻辑和你原来的递归逻辑完全一致,但不会产生递归调用栈的累积,也就不会触发StackOverflowError。

额外提示

如果你确实想确认Stack的容量情况,可以调用capacity()方法(继承自Vector)查看当前的底层容量,size()方法查看实际元素数量,两者是不同的概念:

  • size():当前Stack中的元素个数
  • capacity():底层数组的总容量(可以容纳的元素数,不扩容的情况下)

内容的提问来源于stack exchange,提问作者Gaurav Agarwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:47:30