java中list.remove(item); // 直接移除会导致ConcurrentModificationException

发布于:2025-07-10 ⋅ 阅读:(22) ⋅ 点赞:(0)

在 Java 中,如果你在遍历集合(如 List)的过程中直接使用 list.remove(item),是有可能抛出 ConcurrentModificationException 异常的。

为什么会抛出 ConcurrentModificationException?

这是因为在使用 增强型 for 循环(for-each) 或 Iterator 遍历时,Java 会检查集合是否被“结构性修改”(如添加、删除元素),如果检测到修改就会抛出异常。
错误示例:

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));

for (String item : list) {
    if ("b".equals(item)) {
        list.remove(item); // 抛出 ConcurrentModificationException
    }
}

 正确做法:使用 Iterator
要在遍历时安全地移除元素,应该使用 Iterator 的 remove() 方法:

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    if ("b".equals(item)) {
        iterator.remove(); // 安全地移除元素
    }
}

 iterator.remove() 是唯一允许在遍历过程中安全删除元素的方法。

 替代方案(Java 8+)

方式一:使用 removeIf()
如果你只是想根据条件移除元素,可以使用简洁的 removeIf():

list.removeIf(item -> "b".equals(item));

这行代码会移除所有满足条件的元素,内部已经处理了并发修改问题。

 多线程下修改 List

如果你是在 多线程环境中操作同一个 List,即使使用了 Iterator,也可能会出现并发问题。这时应使用线程安全的集合类:
推荐方式:
使用 Collections.synchronizedList
或者使用 CopyOnWriteArrayList(适用于读多写少场景)
示例:

List<String> list = new CopyOnWriteArrayList<>(Arrays.asList("a", "b", "c"));

for (String item : list) {
    if ("b".equals(item)) {
        list.remove(item); // 在 CopyOnWriteArrayList 中是安全的
    }
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到