集合遍历中操作异常解决
来源:互联网 发布:森林减少的数据 编辑:程序博客网 时间:2024/06/04 18:44
在集合操作的时候,我们通常会使用foreach增强for循环遍历集合,比如我们想输出集合中的每个元素,我们可以使用for循环遍历。代码如下:
//初始化一个集合static List< String > list = new ArrayList< String >();list.add("1");list.add("2");list.add("3");list.add("4"); //遍历集合for (String l : list) {System.out.println(l);}
但是当我们在使用增强for循环的时候,如果我们想在循环中删除一个或者多个元素的时候,直接调运集合的remove()方法是不行的,会报异常:java.util.ConcurrentModificationException。
for (String l : list) {if (l.equals("1")) {list.remove(l);}}
究其原因,是因为我们在使用集合的remove()操作的时候,java底层会去执行一个modCount++操作,修改modCount这个变量的值。同时我们在执行增强for循环的时候,本质上是在使用集合的Iterator,而这个Iterator也会维护这个modCount的变量,此外它还维护一个expectedModCount变量。也就是说集合本身会维护modCount变量,Iterator会维护modCount和exceptionModCount变量。但是每次在Iterator执行操作的时候,都会先检查modCount变量和exceptionModCount的值是否一致,源代码如下:
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException();}
在检查modCount和exceptionModCount的值是否还相同,如果不相同,那么就报异常。在上面for循环的操作中,我们使用for循环遍历,但是在循环内部使用集合自己的remove方法,这个方法把modCount的值给修改,接下来再遍历的时候,使用到了Iterator的方法,这时再检查那两个变量的时候,因为只有modCount被改了,所以他们不一致了,自然要抛异常。好了,现在明白为什么报异常以后,就知道怎么避免这个问题了。
我们有两个办法可以避免这个异常。
第一,不要使用集合Iterator相关的方法,不涉及到exceptionModCount变量即可,只涉及到modCount变量即可。说具体点就是我们不要使用任何和Iterator相关的东西,也就是说不要使用争强for循环,当然这样就不会执行检查两个变量是否相同了。代码体现如下:
for (int i = 0; i < list.size(); i++) {if (list.get(i).equals("4")) {// list.remove(i);list.remove(list.get(i));//只使用到集合自己的remove方法,不会涉及到exceptionModCount}}
第二,我们每次操作的时候,不要只修改modCount变量,同时修改exceptionModCount变量,使之永远保持一致即可。也就是说不要使用集合自己remove方法,使用iterator提供的方法。代码体现如下:
Iterator< String > itList = list.iterator();while (itList.hasNext()) {if (itList.next().equals("1")) {itList.remove();//使用Iterator的remove方法,这样modCount和exceptionModCount永远是一致的}}
第三,我们还有个一个择中的办法。首先使用iterator的方法得到所有需要被删除的元素,然后在使用集合的removeAll()方法一次性将要删的的元素都删除,在removeAll方法中,我们也不会涉及到检查modCount和exceptionModCount是否一致的问题。
这里只列举了List集合的例子,对于Set集合和Map集合是相同的。
- 集合遍历中操作异常解决
- 关于java集合的遍历以及ConcurrentModificationException(并发操作异常)
- 遍历集合ConcurrentModificationException异常
- java集合遍历过程中报ConcurrentModificationException异常
- Iterator遍历器删除集合中元素抛异常
- 集合操作 异常处理
- ASP中遍历和操作Application对象的集合
- ASP中遍历和操作Application对象的集合
- 遍历集合时删除、增加、修改等操作导致的异常处理
- Java_集合操作_遍历集合方法
- 关于迭代器的在集合遍历中发生的并发修改异常(java.util.ConcurrentModificationException
- mybatis中如何遍历集合
- freeMark中遍历list集合
- JS遍历list异常情况解决
- List集合操作一:遍历与查找
- List集合操作一:遍历与查找
- java lambda表达式 遍历操作集合
- 集合遍历操作:Collection及Iterator接口
- oracle处理父子节点关系
- VS2010中打开VS2013的C#项目的方法
- SpringMVC处理Date类型的成员变量方法
- [zz]myeclipse开启和关闭html,jsp等页面的可视化编辑器
- 机器学习-广义线性模型
- 集合遍历中操作异常解决
- Hibernate对象3种状态
- C/C++ 笔试、面试题目大汇总2
- Lucene使用说明
- Windows Azure系列-- Azure Table的CRUD操作
- slf4j日志的使用
- AIDL 进程间通信
- Log4j使用说明
- webservice框架jersey简单总结