4.11 java.util.ConcurrentModificationException

这篇文章展示了如何解决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);
        }
    }
}

上面的代码是没问题的,因为他们没用在底层使用数组作为底层的数据结构。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容