for(User u : new ArrayList<User> ()){ ...... UserDao.update(u) } 迭代不能进行删除修改操作,会引发异常·只适合查看·
遍历的时候不要同时出现remove等操作
改用for循环,不用增强for—each这样的循环,for-each实质上是使用迭代器了。
导致原因:集合框架的非线性支持,对于所有非支持线程操作的集合都会出现这种错误,建议看一下java集合的API 解决方案: 1。使用迭代器: (先将迭代器中的对象删除,原因迭代器的快速失败行为) List list = new List(); list.add(...); Iterator iter = list.iterator(); while(iter.hasNext()){ Student stu = iter.next(); if("ss".equals(str){ iter.remove(); list.remove(stu) } } 2。使用clone List list = new List(); list.add(...); List l = list.clone(); (但是集合框架不支持克隆仅仅作为参考,同时注意克隆的作用域,protect) 再次解决方案: list l = list; while(iter.hasNext()){ Student stu = iter.next(); if("ss".equals(str){ l.remove(stu) } } list = l; 3。 在此不建议使用 变形的for 循环 for(Student stu:list) 在中方式无法用iterator 删除,即方案一 方案2或对效率有影响
补充楼上: 注意,此实现不是同步的。如果多个线程同时访问一个哈希 set,而其中至少一个线程修改了该 set,那么它必须 保持外部同步。这通常是通过对自然封装该 set 的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSet 方法来“包装” set。最好在创建时完成这一操作,以防止对该 set 进行意外的不同步访问: Set s = Collections.synchronizedSet(new HashSet(...));此类的 iterator 方法返回的迭代器是快速失败 的:在创建迭代器之后,如果对 set 进行修改,除非通过迭代器自身的 remove 方法,否则在任何时间以任何方式对其进行修改,Iterator 都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来在某个不确定时间发生任意不确定行为的风险。 注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器在尽最大努力抛出 以上为api,根本原因是,set ,list ,map 不支持 多线程
如果是一个事先已经查询出来的arraylist对象,那么你在遍历它的过程中进行其他修改操作,哪add或remove等。要想避免这种情况你可以对这个对象进行克隆,保存一个副本!
如果是一个事先已经查询出来的arraylist对象,那么你在遍历它的过程中就不能再执行其他修改操作,如add或remove等。要想避免这种情况你可以对这个对象进行克隆,保存一个副本!
for循环比较里怎么会new一个ArrayList,
另外通过List里的数据去更新数据库,也不会出ConcurrentModificationException异常,
应该是在for里对List里的数据进行了增删操作才会有吧。
如果你真想在在循环中删除列表项,建议你不要用泛型,改用for(i = list.size(); i >= 0; i--){}这样的循环,切记是从后向前删(注意索引)。
这种只能用于查看,不能直接对原对象进行其他操作。
因为你的循环满足条件时,在循环内可能那个位置的数据被其它线程给删除了。
所以你一定要判断
list.get(i) !=null
......
UserDao.update(u)
}
迭代不能进行删除修改操作,会引发异常·只适合查看·
解决方案:
1。使用迭代器: (先将迭代器中的对象删除,原因迭代器的快速失败行为)
List list = new List();
list.add(...);
Iterator iter = list.iterator();
while(iter.hasNext()){
Student stu = iter.next();
if("ss".equals(str){
iter.remove();
list.remove(stu)
}
}
2。使用clone
List list = new List();
list.add(...);
List l = list.clone(); (但是集合框架不支持克隆仅仅作为参考,同时注意克隆的作用域,protect)
再次解决方案: list l = list;
while(iter.hasNext()){
Student stu = iter.next();
if("ss".equals(str){
l.remove(stu)
}
}
list = l;
3。 在此不建议使用 变形的for 循环 for(Student stu:list)
在中方式无法用iterator 删除,即方案一
方案2或对效率有影响
注意,此实现不是同步的。如果多个线程同时访问一个哈希 set,而其中至少一个线程修改了该 set,那么它必须 保持外部同步。这通常是通过对自然封装该 set 的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSet 方法来“包装” set。最好在创建时完成这一操作,以防止对该 set 进行意外的不同步访问: Set s = Collections.synchronizedSet(new HashSet(...));此类的 iterator 方法返回的迭代器是快速失败 的:在创建迭代器之后,如果对 set 进行修改,除非通过迭代器自身的 remove 方法,否则在任何时间以任何方式对其进行修改,Iterator 都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来在某个不确定时间发生任意不确定行为的风险。 注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器在尽最大努力抛出
以上为api,根本原因是,set ,list ,map 不支持 多线程