繁体   English   中英

ArrayList和IndexOutOfBounds异常

[英]ArrayList and IndexOutOfBounds exception

因此,我正在编写的某些代码超出了索引范围。 我不明白的是,我实际上知道我要使用的索引元素已经存在。

这是代码:

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

    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的索引?

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

第一次迭代:i = 0

[1, 2, 3]

第二次迭代:i = 1

[2, 3]

第三次迭代:i = 2

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

从头到尾进行迭代。 这将使其正确且速度更快,因为列表不必从右到左复制所有元素。

问题出在以下循环中:

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

删除元素后,列表大小也会减小。 如果从列表大小3开始,则在第3次迭代中,索引的大小从2 as initially 0 then 1 then 2变为2 as initially 0 then 1 then 2变为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;
    }

这样看。

当您开始for循环时,ArrayList的大小为x

调用remove() ,将从列表中获取一个元素。 因此大小为x-1

但是,如果您要不断增加要删除的元素,那么最终您将要删除不再存在的索引。 请记住,当您调用remove()时,数组列表的内容会移动。 因此,如果您之前有0,1,2,3并已将其删除2。该列表为0,1,3。 如果调用最初有效的remove(4) ,则会收到“越界”异常

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM