这篇文章是讨论如何解决ArrayList的java.util.ConcurrentModificationException异常问题。
错误的提示信息一般如下:
1 2 3 4 5
| Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) ... ...
|
问题的根本原因
你可能是在迭代的同时根据某条件删除了一些元素。比如,下面的情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import java.util.ArrayList; import java.util.List; public class AddRemoveListElement { public static void main(String args[]) { List<String> list = new ArrayList<String>(); list.add("A"); list.add("B"); for (String s : list) { if (s.equals("B")) { list.remove(s); } } } }
|
你将会得到如下错误:
解决方案1
可以使用Iterator来解决这个问题。Iterators可以在迭代的时候删除元素。
1 2 3 4 5 6 7 8
| Iterator<String> iter = list.iterator(); while(iter.hasNext()){ String str = iter.next(); if( str.equals("B") ) { iter.remove(); } }
|
解决方案2
不使用ArrayList,改用CopyOnWriteArrayList来解决。CopyOnWriteArrayList 是线程安全的ArrayList,为了解决可变操作(add, set,等等),实现方式都是通过底层数组的复制。
1 2 3 4 5 6 7 8 9 10 11
| public static void main(String args[]) { List<String> list = new CopyOnWriteArrayList<String>(); list.add("A"); list.add("B"); for (String s : list) { if (s.equals("B")) { list.remove(s); } } }
|
其他集合类型呢?
1 2 3 4 5 6 7 8 9 10 11
| public static void main(String args[]) { Set<String> set = new HashSet<String>(); set.add("A"); set.add("B"); for (String s : set) { if (s.equals("B")) { set.remove(s); } } }
|
1 2 3 4 5 6 7 8 9 10 11
| public static void main(String args[]) { LinkedList<String> llist = new LinkedList<String>(); llist.add("A"); llist.add("B"); for (String s : llist) { if (s.equals("B")) { llist.remove(s); } } }
|
上面的代码是可以的,因为它们没有使用阵列中的线数据结构。
参考文档