我遇到了一个问题,我试图遍历存储餐馆对象的arraylist,但循环只通过五个元素中的3个。
我创建了一个测试方法来说明:
public void testLoop() {
ArrayList<Eatery> test = new ArrayList<Eatery>();
test = eateriesListDefault;
for(Eatery e : test) {
MyLog.e(TAG, "Name: " + e.getName());
}
for (int i = 0; i < eateriesListDefault.size(); i++) {
MyLog.e(TAG, "Name " + test.get(i).getName());
test.remove(i);
}
for(Eatery e : test) {
MyLog.e(TAG, "Name " + e.getName());
}
}
此处测试将包含5个餐馆对象。第一个循环成功打印5个名称中的5个。 第二个循环只删除了3个餐馆,因此最后一个循环打印出两个名字。
我尝试过使用
for(Eatery e : eateriesListDefault) {
MyLog.e(TAG, "Name: " + e.getName());
test.remove(e);
}
代替第二个循环,但是我得到并发访问错误。
有谁知道我做错了什么?
答案 0 :(得分:7)
您在每次循环迭代中调用eateriesListDefault.size()
。与此同时,您正在调用test.remove(i)
,每次迭代都会将数组缩短一次。你的循环基本上是这样做的:
i = 0 size = 5 继续
i = 1 size = 4 继续
i = 2 size = 3 继续
i = 3 size = 2 停止
如果你的目标是打印出数组的第一个元素然后删除它,你可以通过这个循环到达那里:
while(!eateriesListDefault.isEmpty()) {
MyLog.e(TAG, "Name " + test.get(0).getName());
test.remove(0);
}
答案 1 :(得分:2)
当循环索引继续增加时,第二个循环会从数组中删除元素。在第四遍,你的循环索引是3,但是eateriesListDefault.size是2,所以循环退出。
请改为尝试:
for ( Iterator<Eatery> it = test.iterator(); it.hasNext(); ) {
MyLog.e(...)
it.remove();
}
如果在迭代期间以除调用Iterator.remove()之外的任何方式修改列表,则未指定迭代器的行为。请参阅Iterator.remove() documentation。
此外,您可能希望制作默认列表的副本。您的“test =”语句只是对同一个列表进行了新的引用。
test = new ArrayList<Eatery>( eateriesListDefault );