这篇文章展示了如何解决ArrayList的java.util.ConcurrentModificationExcepiton。
错误信息展示如下:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
问题
你可能需要遍历ArrayList,并在某些条件下删除一些元素,举个例子,一下代码看起来很合理:
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 可以用来解决这个问题。迭代器准许调用者从底层集合中删除元素。
Iterator<String> iter = list.iterator();
while(iter.hasNext()){
String str = iter.next();
if( str.equals("B") )
{
iter.remove();
}
}
解决方法二
CopyOnWriteArrayList可以用来解决问题。CopyOnWriteArrayList是ArrayList的线程安全变体,其中所有变动(添加,设置等)都是通过对底层数组制作一个新的副本来实现的。
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);
}
}
}
其他Collection 类型如何?
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);
}
}
}
上面的代码是没问题的,因为他们没用在底层使用数组作为底层的数据结构。