迭代集合以添加项目但抛出 ConcurrentModificationException

Rip*_*gat 1 java collections arraylist concurrentmodification

package com.ripal;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Iterator;

public class Outputs {

    public void show() {
        final ArrayList<String> list = new ArrayList<String>();

        list.add("banana");
        list.add("apple");

        Iterator<String> itr = list.iterator();

        Collections.sort(list);
        while (itr.hasNext()) {
            System.out.println(itr.next() + " ");
        }
    }
}

class Test {

    public static void main(String[] args) {
        Outputs outputs = new Outputs();
        outputs.show();
    }
}
Run Code Online (Sandbox Code Playgroud)

Rav*_*ala 5

ArrayList有一个快速失败迭代器。您只能通过迭代器修改集合。调用迭代器方法后,会很快检测到在外部进行的任何其他修改,并ConcurrentModificationException抛出 a 。在您的情况下,创建迭代器后,您对数组进行排序,并且排序例程会修改数组的内容,从而导致ConcurrentModificationException使用迭代器。要解决此问题,只需在创建迭代器之前执行排序即可。它看起来是这样的。

Collections.sort(list);
Iterator<String> itr = list.iterator();
Run Code Online (Sandbox Code Playgroud)

  • 另一种方法是在不需要时不处理迭代器: `for(String s: list) System.out.println(s);` (行尾的空白无论如何都是毫无意义的,替代方法是 `System .out.println(String.join(" ", list));` 如果这是实际意图)。 (4认同)
  • 有趣的是,ArrayList 的文档说,如果您_结构上_修改列表,则会抛出 CME;但对 ArrayList 进行排序并不是结构修改(它只是在数组中移动元素)(例如,您可以对无法进行结构修改的列表进行排序,“Arrays.asList”)。但是源代码[显式更新了modCount](https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/share/classes/java/util/ArrayList.java#L1752)。 (3认同)