List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
System.out.println("执行if语句成功");
}
}
直接运行这段代码是没什么问题的,数组list能成功删除元素1,也能打印对应语句。
但是,我们进行如下任意一种操作:
若把list.remove(item)换成list.add(“3”); 报错
若在第6行添加list.add(“3”); 报错
若把if语句中的“1”换成“2”, 报错
why?
1.![](https://img.haomeiwen.com/i19596990/47545c125125d379.jpg)
这涉及多线程操作,Iterator是不支持多线程操作的,List类会在内部维护一个modCount的变量,用来记录修改次数。也就每次add或者remove它的值都会加1
在 foreach 循环中执行 list.add(item);,对 list 对象的 modCount 值进行了修改,而 list 对象的迭代器的 expectedModCount 值未进行修改, 但此时调用了foreach的next()方法之后,就用进行校验checkForComodification(),发现不一样抛出异常。,因此抛出了ConcurrentModificationException异常。
3.若把if语句中的“1”换成“2”为什么报错呢?
至于为什么删除“1”就可以呢,原因在于foreach和迭代器的hasNext()方法,foreach这个语法,实际上就是
while(itr.hasNext()){
itr.next()
}
所以每次循环都会先执行hasNext(),那么看看ArrayList的hasNext()是怎么写的:
public boolean hasNext() {
return cursor != size;
}
cursor代表当前迭代器的游标,如果删除了,cursor!=size为false ,hasNext直接返回false,就不执行next()了所以,不会抛出异常。
如果删除的话有两种办法
//通过迭代器移除等于11的元素
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
String item = iterator.next();
if("11".equals(item)) {
iterator.remove();
}
}
//jdk1.8移除等于11的元素
list.removeIf(item -> "11".equals(item));
网友评论