java 技术含量_JAVA

博客主要围绕Java中遍历删除集合元素时出现的ConcurrentModificationException异常展开。先给出示例代码展示异常,接着分析异常原因是迭代器大小与原始大小不一致。然后提供解决方法,如不混用遍历方法,还介绍了遍历时再遍历删除的两种进阶解决办法。

这个异常一般在我们遍历删除集合元素时出现。写了下面这个代码来展示这个异常。

[java]

import java.util.ArrayList;

import java.util.List;

public class ExeptionTest {

public static void main(String[] args) {

List list = new ArrayList();

list.add("a");

list.add("b");

list.add("c");

list.add("d");

list.add("e");

for (String s : list) {

if ("c".equals(s)) {

list.remove("c");

}

}

}

}

[/java]

控制台报错如下:

[java]

Exception in thread "main" java.util.ConcurrentModificationException

at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)

at java.util.ArrayList$Itr.next(ArrayList.java:791)

at ExeptionTest.main(ExeptionTest.java:14)

[/java]

出现异常原因分析:

for循环执行时内部实际是调用的List实现了Iterator接口的方法,换句话说所有实现了Iterator接口的都可以使用for。追查JDK源码可以看到异常报错正是来自ArrayList内部实现的迭代器类Itr的checkForComodification()方法。

[java]

final void checkForComodification() {

if (modCount != expectedModCount)

throw new ConcurrentModificationException();

}

[/java]

其实这个方法只做了一件事就是检查迭代器当前的大小是否和原始大小一样,如果不一样。则认为原始的集合已经在其它地方被修改,故而出现此异常。

解决方法

既然报错的原因清楚了,那么我们只要不混用两种遍历方法就没有问题了。

[java]

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

public class ExeptionTest {

public static void main(String[] args) {

List list = new ArrayList();

list.add("a");

list.add("b");

list.add("c");

list.add("d");

list.add("e");

// 法一

for (int i = 0; i < list.size(); i++) {

if (i == 2) {

list.remove(i);

}

}

System.out.println(list);

// 法二

Iterator iter = list.iterator();

while (iter.hasNext()) {

if ("d".equals(iter.next())) {

iter.remove();

}

}

System.out.println(list);

}

}

[/java]

ConcurrentModificationException进阶

某些时候我们可能会遇到遍历时还要再遍历删除的情况。这时该怎么解决呢?对于这样的情况我们有二种解决办法

将要删除的对象收集到另一个集合中一起删除[java]import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

public class ExeptionTest {

public static void main(String[] args) {

List list = new ArrayList();

list.add("a");

list.add("b");

list.add("c");

list.add("d");

list.add("e");

Iterator iter = list.iterator();

List toBeRemove = new ArrayList();

String t = null;

while (iter.hasNext()) {

t = iter.next();

if (t.equals("c")) {

toBeRemove.add(t);

}

}

//使用removeAll一起删除

list.removeAll(toBeRemove);

System.out.println(list);

}

}[/java]

第一轮遍历时使用复制对象。[java]import java.util.ArrayList;

import java.util.List;

public class ExeptionTest {

public static void main(String[] args) {

List list = new ArrayList();

list.add("a");

list.add("b");

list.add("c");

list.add("d");

list.add("e");

// 遍历复制集合,此时实际使用的是iterator.

for (String s : new ArrayList(list)) {

if (s.equals("c"))

//移除时使用的是非iterator的方式

list.remove(s);

}

System.out.println(list);

}

}

[/java]

本次的文章就写到这里,如有疏漏,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值