java 遍历list、set时 删除元素 java.util.ConcurrentModificationException

1,一般情况下,可使用 iterator 遍历list、set同时删除其中的某些元素,例如:

Iterator<String> it = collection.iterator();
while (it.hasNext()) {
    String str = it.next();
    if (......) {
        it.remove();
        // System.out.print(collection);
    }
}

2,而 ~~  有递归时,如下:

对于List:

    public void recursiveFunc(ArrayList<String> wordList) {
        System.out.println(wordList);
        Iterator<String> it = wordList.iterator();
        while (it.hasNext()) {
            String s = it.next();
            if(......){
                it.remove();
                recursiveFunc(wordList); //把删除某元素之后的 list 当参数传进行递归时,没有任何问题
            }
        }
    }

对于Set:

   public void recursiveFunc(Set<String> set) {
        System.out.print(set);
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String s = it.next();
            if(......){
                it.remove();
                recursiveFunc(set);  // 把删除某元素之后的 set当参数传进行递归时,就会报错ConcurrentModificationException
            }
        }

    }

    ——需要注意一下,

    解决方法:new一个set,把remove()某元素之后的数据集copy到new出来的set中当 递归 参数。

`java.util.ConcurrentModificationException`异常通常发生在多线程环境下,当程序试图同修改一个集合(如ListSet或Map)的内容,而这些集合是被其他线程正在遍历候。这是因为Java的集合类内部维护了一个迭代器,这个迭代器假设集合的内容不会改变,但在并发情况下,如果线程A正在遍历,线程B修改了集合,就会导致迭代器无法正确跟踪元素,从而抛出此异常。 要解决这个问题,可以采取以下几种策略: 1. **避免在迭代过程中修改集合**:如果你知道可能会有修改,尽量在遍历之前完成所有可能的修改操作,或者使用不可变集合(如`Collections.unmodifiableList()`)。 2. **同步操作**:如果必须在迭代过程中修改,确保对集合的修改操作是在同步块中进行,这样可以保证同一间只有一个线程可以修改集合。 3. **使用并发集合**:Java提供了一些并发版本的集合,如`CopyOnWriteArrayList`和`ConcurrentHashMap`,它们在修改会创建新的视图,避免了直接抛出异常,而是返回一个新的结果。 4. **使用`Iterator.remove()`替换`List.remove()`**:在`List`迭代器上调用`remove()`方法,不会抛出`ConcurrentModificationException`,但会导致迭代提前结束。 在你给出的代码示例中,删除元素引发异常是因为尝试在线程安全的迭代中修改了集合结构。正确的做法是先移除元素再迭代,或者在遍历使用`Iterator.remove()`替换`List.remove()`。 ```java // 错误示例 List<Integer> list = ...; Iterator<Integer> it = list.iterator(); while (it.hasNext()) { if (it.next().equals(3)) { // 不应在迭代过程中修改 it.remove(); // 这里会抛出异常 } } // 正确示例 List<Integer> list = ...; Integer target = 3; list.remove(target); // 先移除元素 for (Integer element : list) { // 现在可以安全地遍历 } ``` [^1]: java.util.ConcurrentModificationException异常原因及解决方法。@TOC 欢迎使用Markdown编辑器 : java.util.ConcurrentModificationException异常原因及解决方法。复制代码 上述代码在删除value=3的元素,报java.util.ConcurrentModificationException异常,如下图。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值