Java中使用集合遍历时修改元素产生的异常解决

  • 问题:在使用 for-each 进行集合遍历的过程中,对某一元素进行了修改将会报出 java.util.ConcurrentModificationException 异常,如下所示:

    for (Student s : stus){
        if(id.equals(s.getId())){
            stus.remove(s);
        }
    }
    
  • 解决方法

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