遍历集合删除元素使用remove时抛出异常的解决方式

循环集合的方法有三种:

  • 简单for循环

  • iterator循环

  • 增强for循环

例子如下:

List<Long> fList = new ArrayList<Long>();
fList.add(1L);
fList.add(2L);
fList.add(3L);
fList.add(4L);
// 简单for循环
for(int n = 0; n < fList.size(); n++){
System.out.println(fList.get(n).longValue());
}
// iterator循环
Iterator<Long> iter = fList.iterator();
while(iter.hasNext()){
System.out.println(iter.next().longValue());
}
// 增强for循环
for(Long f : fList){
System.out.println(f.longValue());
}

删除集合元素:

当我们在遍历某个集合的时候,经常需要删除该集合中满足条件的元素,例如:

遍历集合删除元素使用remove时抛出异常的解决方式

但是在运行的时候,并不会如我们期望的一样操作成功,控制台会报错,如下:

遍历集合删除元素使用remove时抛出异常的解决方式

原因分析:

这是并发修改异常错误,经过网上搜索了解到,原来是集合遍历原理导致的,具体原因是这样的:

不管是哪种方式的集合遍历方法,当我们在遍历某个集合的时候,Collection的实现并没有同步化,如果在多线程应用程序中出现同时访问,而且出现修改操作的时候都要求外部操作同步化;调用遍历操作获得的遍历对象在多线程修改集合的时候也自动失效,并抛出java.util.ConcurrentModificationException。这种实现机制是fail-fast,对外部 的修改并不能提供任何保证。遍历对象在被创建的时候,同时创建了一张单链的索引表,指针指向原始数据对象,只能顺序读取,不能逆向操作,而set、list等集合是动态、可变的数据结构;当原始对象改变时,索引并为改变,因此,索引指针继续移动的时候,找不到要迭代的对象就会报错。

解决方法:

将删除对象放在一个临时的集合中,最后使执行removeAll方法移除,如下:

遍历集合删除元素使用remove时抛出异常的解决方式