Java中使用集合遍历时修改元素产生的异常解决
-
问题:在使用 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 等操作。