所以我在写一些代码时得到一个索引超出范围的异常。我不明白的是,我知道我正在尝试使用的索引元素存在。
以下是代码:
我有一个数组列表的构造函数
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?
答案 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异常