从数组中读取java堆栈会抛出ArrayIndexOutOfBoundsException

时间:2012-02-29 02:13:58

标签: java stack indexoutofboundsexception

我需要从数组填充堆栈,然后按顺序打印出元素,然后再次颠倒顺序。我遇到的问题是我得到一个ArrayIndexOutOfBoundsException并且无法弄清楚它来自哪里。我已经尝试了通过调试,看起来我正在弹出它永远不会到达最后一个元素的元素。以下是我的代码:

public class arrayStack {

    private int top;
    private String[] storage;

    public arrayStack(int capacity)
    {
        storage = new String[capacity];
        top = -1;
    }

    public boolean isEmpty() {
        return (top == 0);
    }

    String peek() {
        return storage[top];    
    }

    String pop() {
        top--;
        return storage[top];
    }

    public void push(String str) {
        top++;
        storage[top] = str;
    }

}

StackMain.java:

public class StackMain {

    public static void main(String[] args) {
        //int j = 5;
        String[] list = new String[5];

        list[0] = "Beware";
        list[1] = "The";
        list[2] = "Ides";
        list[3] = "Of";
        list[4] = "March";

        arrayStack stack = new arrayStack(5);

        for(int i = 0; i < list.length; i++)
        {
            stack.push(list[i]);
        }

        for(int j = 0; j < list.length; j++)
            System.out.println(stack.pop());

    }

}

8 个答案:

答案 0 :(得分:3)

pop()中,您需要返回弹出的项目,该项目是旧值top的索引处的项目。最干净的方法是将功能更改为

String pop() {
    return storage[top--];
}

修改
您还需要将isEmpty()更改为return (top == -1)。您还可以将实现更改为使用size(元素数)而不是top(最高元素的索引),如同其他提到的那样。

答案 1 :(得分:1)

arrayStack的构造函数中,您应该将top设置为0,而不是-1。在isEmpty方法中,您甚至可以检查top == 0,因此top == 0显示为空,而不是top == -1。这就是为什么在从堆栈中弹出值时总是会错过最后一个元素的原因;将第一个元素增加top为0。

哦,我错过了汤姆所说的,下面:在找到顶部的值之前递减top将返回错误的元素。他的下面的代码是可取的,但对于初学者来说这可能更容易理解:

public String pop() {
    String topValue = storage[top];
    top--;
    return topValue;
}

答案 2 :(得分:1)

如果你push(String)只有一个元素,top被初始化为-1,那么top之后的值是什么?

现在看一下你的pop()函数,它会在尝试获取所请求的元素之前递减顶部的,所以如果你只推了一个,它会尝试访问什么数组索引元件?

答案 3 :(得分:1)

由于你在-1处开始top,一旦你从字符串数组top添加了5个元素将是4,这是不正确的,因为你有5个元素。

然后当您尝试弹出堆叠5次时,top会返回-1并且storage[-1]不存在,因此您获得了ArrayIndexOutOfBoundsException

从0开始top

或者,如果在从堆栈中检索元素后递减top,则不会出现错误;但最好从top开始,因为top实际上代表了堆栈中元素的数量。

答案 4 :(得分:1)

请将问题标记为作业。并且遇到问题,问题出在pop()函数中。您首先递减top的值,然后返回该元素。但是当你检查push()函数时,首先递增然后添加元素。因此,如果您在从堆栈中获取元素后移动top--,您的问题将得到解决。

答案 5 :(得分:1)

你的pop方法不正确。在这里的代码中,top从负1开始。

按下元素时,top变为0。 弹出元素时,在访问元素之前,top会变为-1。

另外,您的空方法不正确。在堆栈的初始状态中,top = -1,isEmpty检查它是否返回0.最初堆栈应为空。

答案 6 :(得分:1)

必须更改pop()函数。您必须将存储[pop]存储在临时变量中,然后将top减1,然后返回临时变量

答案 7 :(得分:1)

如果你可以包含java 1.5泛型工具来实现堆栈,那将是很棒的。然后你的堆栈会更灵活。它可以容纳任何类型的对象(在你的情况下只有字符串) 还有一个建议是在pop方法中你应该告诉垃圾收集器丢弃到poped对象,如下所示。 (在使用泛型的情况下)以下是有效的Java版本2中提到的更灵活的堆栈实现。

// Initial attempt to generify Stack = won’t compile!
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = (E[])new E[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size==0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}