【转】[J] 再次遭遇 Iterator 遍历 ArrayList 元素时执行删除操作

本文解析了在Java中使用ArrayList与Iterator组合删除指定元素时遇到的ConcurrentModificationException异常问题,并提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

已经是第二次碰到这个题目了。如果你以前没有专门的看这一块的话,很有可能你给出的答案是不正确的。

题目要求:

给出如下的程序,问如何删除 BBB 对应的元素,请把代码补充完整。

给出的代码框架:

[CODE]

import java.util.*;

class ArrayListTest {
public static void main(String[] args) {
   ArrayList<String> list = new ArrayList<String>();
   list.add("AAA");
   list.add("BBB");
   list.add("CCC");
   list.add("DDD");
  
   System.out.println(list);
  
   Iterator<String> it = list.iterator();
   while(it.hasNext()) {   
   // 需要实现的代码
   }
  
   System.out.println(list);
}
}

[CODE]

这块代码的意图很明显,通过 iterator的方式删除元素。

如果你给出的代码是这个样子:

String toDel = it.next();

if(toDel.equals("BBB")) {   
list.remove(toDel);   
}

那么恭喜你,答错了! 运行时会抛出异常:

Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at ArrayListTest.main(ArrayListTest.java:63)

抛出异常java.util.ConcurrentModification,为什么?这和 Iterator的内部实现有关系。有兴趣的话可以查看 Iterator 的源代码实现。
这里廖雪峰的一篇文章: Java源码分析:深入探讨Iterator模式 
供参考。

要怎么实现呢? 是这样的,再添加一条语句:

String toDel = it.next();

if(toDel.equals("BBB")) {
it.remove(toDel); // 需要添加这个语句  
list.remove(toDel);
   
}

调用 Iterator自身的remove()方法的目的是一并删除当前元素,它会自动同步expectedModCount和modCount的值。所以 checkForComodification()方法就不会抛出ConcurrentModificationException 异常了。

查看源代码,Iterator 中 remove() 方法的实现如下:

public void remove() {
    ...
    AbstractList.this.remove(lastRet);
    ...
    // 在调用了集合的remove()方法之后重新设置了expectedModCount:
    expectedModCount = modCount;
    ...
}

文章中也给出建议:

要确保遍历过程顺利完成,必须保证遍历过程中不更改集合的内容(Iterator的remove()方法除外),因此,确保遍历可靠的原则是只在一个线程中使用这个集合,或者在多线程中对遍历代码进行同步。

 

所以,根据题目要求,所要完成的完整代码为:

[CODE]

import java.util.*;

class ArrayListTest {
public static void main(String[] args) {
   ArrayList<String> list = new ArrayList<String>();
   list.add("AAA");
   list.add("BBB");
   list.add("CCC");
   list.add("DDD");
  
   System.out.println(list);
  
   Iterator<String> it = list.iterator();
   while(it.hasNext()) {   
    String toDel = it.next();

    if(toDel.equals("BBB")) {
    it.remove(toDel); // 需要添加这个语句  
     list.remove(toDel);   
    }
   }
  
   System.out.println(list);
}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值