Java List在进行remove()方法是通常容易踩坑,主要有一下几点
循环时:问题在于,删除某个元素后,因为删除元素后,后面的元素都往前移动了一位,而你的索引+1,所以实际访问的元素相对于删除的元素中间间隔了一位。
几种常见方法
- 使用for循环不进行额外处理时(错误)
//错误的方法
for(int i=0;i<list.size();i++) {
if(list.get(i)%2==0) {
list.remove(i);
}
}
2.使用foreach循环(错误)
for(Integer i:list) {
if(i%2==0) {
list.remove(i);
}
}
抛出异常:java.util.ConcurrentModificationException;
foreach的本质是使用迭代器实现,每次进入for (Integer i:list) 时,会调用ListItr.next()方法;
继而调用checkForComodification()方法, checkForComodification()方法对操作集合的次数进行了判断,如果当前对集合的操作次数与生成迭代器时不同,抛出异常
public E next() {
checkForComodification();
if (!hasNext()) {
throw new NoSuchElementException();
}
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
// checkForComodification()方法对集合遍历前被修改的次数与现在被修改的次数做出对比
final void checkForComodification() {
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
- 使用for循环,并且同时改变索引;(正确)
//正确
for(int i=0;i<list.size();i++) {
if(list.get(i)%2==0) {
list.remove(i);
i--;//在元素被移除掉后,进行索引后移
}
}
- 使用for循环,倒序进行;(正确)
//正确
for(int i=list.size()-1;i>&#