【问题标题】:Reason for java.lang.ArrayIndexOutOfBoundsExceptionjava.lang.ArrayIndexOutOfBoundsException 的原因
【发布时间】:2015-12-30 05:11:01
【问题描述】:

知道这条线有什么问题吗? outStr[i]=(String) s.pop();

import java.util.ArrayList;
import java.util.Scanner;

public class StringWordReverse {

    public String[] StringToWord(){
        Scanner sc = new Scanner(System.in);
        sc.useDelimiter(" ");
        ArrayList<String> wordList= new ArrayList<String>();
        String sc_in= sc.nextLine();
        String[] sc_split=sc_in.split(" +");
        for (int i=0; i<sc_split.length; i++){
            wordList.add(sc_split[i]);
        }

        String[] stringArr= new String[wordList.size()];
        for (int i=0; i<wordList.size(); i++){
            stringArr[i]= wordList.get(i);
        }
        return stringArr;


    }

    public String[] reverseWords(String[] words){
        Stack<String> s= new Stack<String>();
        String[] outStr=new String[words.length];
        for (int i=0; i<words.length; i++){
            s.push(words[i]);
        }
        for (int i=0; i<words.length; i++){
            System.out.println(s.stackSize());
            outStr[i]=(String) s.pop();
        }

        return outStr;  

    }

    public static void main(String[] argc){
        StringWordReverse swr = new StringWordReverse();


        String[] inputWords= swr.StringToWord();
        String[] outputWords=swr.reverseWords(inputWords);
        for (int i=0; i<outputWords.length;i++)
            System.out.println(outputWords[i]);


        return;
    }



}

这是我的 Stack 类:

    import java.util.ArrayList;

public class Stack<E> {
    private ArrayList<E> s = new ArrayList<E>();
    private static int size=0;

    public void push(E item){
        s.add(item);
        size++;
        return;
    }

    public E pop(){
        size--;
        return s.remove(size-1);

    }

    public int stackSize(){
        return size;
    }


}

这是我收到的错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.elementData(ArrayList.java:400)
    at java.util.ArrayList.remove(ArrayList.java:477)
    at XYZ.Stack.pop(Stack.java:16)
    at XYZ.StringWordReverse.reverseWords(StringWordReverse.java:35)
    at XYZ.StringWordReverse.main(StringWordReverse.java:47)

【问题讨论】:

  • 你不会让size 在你 push 的时候变大,所以 pop 总是试图在堆栈中取第 -1 个东西。与其持有一个单独的size 变量,不如直接使用s.size()
  • 在回答任何问题之前,我会告诉您相信您的 IDE。黄色下划线不是装饰,而是警告:D 您在应该使用泛型的地方使用原始类型
  • 但是现在你在实际弹出之前减小了大小。因此,如果堆栈有一个元素,则将大小设置为0,然后s.remove(size-1) 真的是s.remove(-1)... 支持List 已经在跟踪它的大小。为什么不相信它?
  • @MonaJalal azurefrog 在他最后的评论中有一个公平的观点。它可以防止你在尺寸上犯错误

标签: java string arraylist stack indexoutofboundsexception


【解决方案1】:

这段代码中的一些错误:

  • 您使用原始类型而不是泛型。让编译器帮助您解决(大多数)运行时类型错误:Stack&lt;String&gt; stack = new Stack&lt;&gt;()

  • Stack.pop 中,您永远不会检查是否有要弹出的元素。您应该对其进行测试并在堆栈为空时抛出异常,例如NoSuchElementException

  • Stack.pop 中,您正在减小大小,然后删除项目size - 1,因此您基本上减少了两次。这应该是:s.remove(--size);

【讨论】:

  • 感谢s.remove(--size); 的澄清:)非常有帮助
【解决方案2】:

使用相同的大小变量从堆栈中取出项目之前,您正在减小大小变量。因此,当您在剩下一个项目的情况下调用 pop 时,您会将大小减小到 0,然后尝试删除位置 -1 的项目。

既然列表中已经有一个大小变量,为什么还要维护自己的大小变量?

【讨论】:

    【解决方案3】:

    尝试更改这部分代码:

    public E pop(){
        size--;
        return s.remove(size-1);
    }
    

    到这里:

    public E pop(){
        return s.remove(size--);
    }
    

    这就是错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多