0

因此,我正在编写的某些代码中出现索引越界异常。我不明白的是,我知道我正在尝试使用的索引元素存在。

这是代码:

我有一个数组列表的构造函数

    public StixBoard(int number)
{
    stixGame = new ArrayList<Integer>(number);

    for (int i = 0; i < number; i++)
    {
        stixGame.add(i);
    }

}

此块生成随机变量 1-3

public int computeMove()
{

    int numberOfStix = (int) (3.0 * Math.random()) + 1;

    return numberOfStix;
}

真的很简单,现在我有一个方法,它采用提供的参数并尝试从数组列表中删除这些数量的元素。可以看到,参数必须在1到3之间,并且必须小于等于数组列表的大小。否则,将提示用户输入另一个数字

public boolean takeStix(int number)
{
    boolean logicVar = false;
    placeHolder = stixGame.size();

    if ((number >= 1 && number <= 3) && number <= placeHolder)
    {
        for (int i = 0; i < number; i++)
        {
            stixGame.remove(i);
            logicVar = true;
        }
    } else if (number > 3 || number > placeHolder)
    {
        do
        {
            System.out
                    .println("Please enter a different number, less than or equal to three.");
            Scanner numberScan = new Scanner(System.in);
            number = numberScan.nextInt();
        } while (number > 3 || number > placeHolder);
    }

    return logicVar;
}

因此,当该程序运行时,computeMove() 方法会生成一个随机 int(假设是计算机玩家的角色)并尝试将该值转换为要从数组列表中删除的索引数。

这最终使我想到了这一点:

How many stix on the table? 4
|||||||||| 4 stix on the table
It's the computer's turn!
The computer chose 3

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at StixBoard.takeStix(StixBoard.java:38)
at StixGame.main(StixGame.java:55)

如您所见,数组列表的大小为 4,但是当计算机掷出 3(这应该让我留下 1)时,我会遇到这个错误。我的数组列表如何从大小为 4 的索引变为大小为 2?

4

3 回答 3

6

您从头到尾遍历您的列表,并在每一步删除一个元素。这使得列表中的所有元素都向左移动。

第一次迭代:i = 0

[1, 2, 3]

第二次迭代:i = 1

[2, 3]

第三次迭代:i = 2

[2] -> IndexOutOfBoudsException. There is no index 2 in this list.

而是从结尾迭代到开头。这将使它正确,并且更快,因为列表不必从右到左复制所有元素。

于 2012-12-07T21:23:09.470 回答
2

问题出在这个循环中:

    for (int i = 0; i < number; i++)
    {
        stixGame.remove(i);
        logicVar = true;
    }

删除元素后,列表大小也会减小。如果您从列表大小 3 开始,那么在第 3 次迭代中,索引变为2 as initially 0 then 1 then 2而大小变为1 as intially 3 then 2 then 1. 因此IndexOutOfBoundException

试试这个:

    for (int i = 0; i < number; i++){
        stixGame.remove(0);//remove 0th index as previous element was removed
        logicVar = true;
    }
于 2012-12-07T21:22:09.027 回答
0

这样看。

当你开始你的 for 循环时, ArrayList 是 size x

当您调用时,remove()您从列表中获取一个元素。所以大小为x-1

但是,如果您不断增加要删除的元素,最终您将删除不再存在的索引。请记住,当您调用remove()数组列表的内容时,会发生移位。因此,如果您之前有 0,1,2,3 并删除了 2。列表是 0,1,3。如果您调用remove(4)最初有效的方法,您将收到 Out Of Bounds 异常

于 2012-12-07T21:26:51.753 回答