ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
// list.add("6");
/**
* 使用这种方式删除是不会报错的,但是会有个问题,就是数据删除不干净
* 也就是我们在删除数据的时候,数据会发生移动,所以有的位置上的数据就删不掉
* 当我们删除位置0上的元素时,2,3,4,5就会移动,此时位置1上的元素是3,所以下次删除的就是3,以此类推,在下一次就是5
* 所以删除完之后还剩下2,4
*/
for(int i=0;i<list.size();i++){
list.remove(list.get(i));
}//2,4
/**
* 使用这种方式遍历数据,只是一种java语法糖,java编译器会使用迭代器的方式重新实现,也就是下面的方式
* 使用这种方式,获取数据是根据cursor来进行获取的,如果我们只有两个元素,那么执行了list删除之后,cursor变成
* 1,然后hasNext比较cursor和size的大小,如果相同,返回就是false,所以就不会进入循环体
* 但是如果数量大于2,则删除一个之后,还会有两个,那么此时hasNext返回true(cursor为1,size为2,不想等),就会进入next,而next里面就会进行
* checkForModification方法的判断,就会判断modCount==expectedModCount是不是相等,不相等就会抛出ConcurrentModificationException异常
* (容器自身的remove方法只会修改modCount的值,并不会修改expectedModCount的值)
* (迭代器的remove方法不仅仅会修改modCount的值,还会将修改后的modCount值重新赋值给expectedModCount)
*/
for(String s:list){
list.remove(s);
}//4
/*Iterator it = list.iterator();
/**
* hasNext 判断cursor和size的数值是否相同
* public boolean hasNext() {
* return cursor != size;
* }
*
*while(it.hasNext()){
* String s = (String)it.next();
* list.remove(s);
*}
*/
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}//4
所以执行上面的代码,是不会抛出异常,执行之后的结果是list还剩下一个元素4,但是如果我们再添加一个元素6,执行删除操作的时候,就会抛出异常。下面这段代码是正确的迭代器使用方式:
Iterator it = list.iterator();
while(it.hasNext()){
it.next();
it.remove();
}
结论:
所以我们在遍历删除arrayList中元素的时候,一定要使用迭代器的方式进行删除;还有一点就是如果我们获得了迭代器,那么之后只要list(容器)被修改了,那么我们获取的迭代器就会失效(modCount值发生变化),所以我们尽可能在我们真的需要迭代器的时候再去获取它。