- 问题:在使用 for-each 进行集合遍历的过程中,对某一元素进行了修改将会报出 java.util.ConcurrentModificationException 异常,如下所示:
for (Student s : stus){
if(id.equals(s.getId())){
stus.remove(s);
}
}
- 解决方法
- 使用临时变量存储需要修改的元素,遍历过程中找到需要修改的元素后退出遍历,再进行修改。如下所示:
for (Student s : stus){
if(id.equals(s.getId())){
temp = s;
break;
}
}
stus.remove(temp);
- 使用 iterator 迭代器来遍历集合,但这种方式仅限于对元素进行 remove 操作:
Iterator it = stus.getIterator();
while(it.hasNext() != null){
if(id.equals(it.next())){
it.remove();
}
}
- 在多线程的情况下,可能会导致一个线程在遍历集合,另一个线程在对集合进行修改的情况,上面两种方式都会产生问题依旧会抛出问题,此时需要加上同步代码块。
synchronized (stus){
for (Student s : stus){
if(id.equals(s.getId())){
temp = s;
break;
}
}
stus.remove(temp);
}
- 除了使用同步代码块,还可以使用 CopyOnWriteArrayList ,它是一个线程安全的集合,解决了多线程问题,同时 Iterator 可以支持 add,clear 等操作。