ArrayList和IndexOutOfBounds异常

时间:2012-12-07 21:19:01

标签: java indexoutofboundsexception

所以我在写一些代码时得到一个索引超出范围的异常。我不明白的是,我知道我正在尝试使用的索引元素存在。

以下是代码:

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

    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?

3 个答案:

答案 0 :(得分:6)

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

第一次迭代:i = 0

[1, 2, 3]

第二次迭代:i = 1

[2, 3]

第三次迭代:i = 2

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

从最后到开头迭代。这将使它更正确,更快,因为列表不必从右到左复制所有元素。

答案 1 :(得分: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;
    }

答案 2 :(得分:0)

以这种方式看待它。

当您启动for循环时,ArrayList的大小为x

当您致电remove()时,您会从列表中选择一个元素。因此大小为x-1

但是如果你不断增加你要删除的元素,最终你将删除一个不再存在的索引。请记住,当您调用remove()时,数组列表的内容会被移位。因此,如果您之前有0,1,2,3并且已删除2.该列表为0,1,3。如果你打电话给最初有效的remove(4),你将获得Out of Bounds异常