list for 循环报错 ConcurrentModificationException

list for 循环报错 ConcurrentModificationException

  • 1、案例一
  • 背景

下面代码执行报错 ConcurrentModificationException

for (String s : list) {
    list.remove(s);
}
  • 分析

java.util.ArrayList.Itr#checkForComodification() 方法报的错。
 

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

(1)foreach方式遍历元素的时候,生成iterator,然后使用iterator遍历。
在生成iterator的时候,会设置expectedModCount参数,初始值为list的个数,此时modCount和exceptedModCount相等。
如果在遍历过程中删除元素,modCount+1,但是exceptedModCount不变,此时modCount和exceptedModCount不一致,就会抛出ConcurrentModificationException异常。
(2)使用iterator直接遍历,使用iterator的remove方法(Iterator子类:java.util.ArrayList.Itr)则正常,因为iterator的remove方法会在内部调用List的remove方法,并且会修改excepedModCount的值,
使modCount和exceptedModCount相等,因此会正常运行

  • 解决

使用迭代器遍历

for(Iterator<String> i = list.iterator(); i.hasNext(); ) {
    String item = i.next();
    i.remove();  //这里调用迭代器的rermove方法而不是集合的remove方法
}

或使用

for (int i =0 ; i < list.size(); i++) {
    String s = list.get(i);
    list.remove(s);
}

 

java.util.ArrayList.Itr中的remove方法:

public void remove() {
    if (lastRet < 0)
        throw new IllegalStateException();
    checkForComodification();

    try {
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount; // 修改excepedModCount的值
    } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
    }
}

 

  • 2、案例二
  • 背景

某个方法中有以下两个操作:
方法中有一个list 的 forEach 循环,在此操作前,有一个对list中的元素进行删除操作的异步方法。具体如下:

public static void test(List<String> list) throws Exception {
	// 异步方法
	ThreadPoolUtil.getInstance().execute(() -> {
		list.removeIf(obj -> Objects.equals(obj,"55"));
	});

	//forEach 循环
	for (String s : list) {
		//
	}
}

 

  • 报错

list for 循环偶尔报错:ConcurrentModificationException

 

  • 分析

原因同上

 

  • 解决
public static void test(List<String> list) throws Exception {
	// 异步方法
	ThreadPoolUtil.getInstance().execute(() -> {
		for(Iterator<String> i = list.iterator(); i.hasNext(); ) {
			String item = i.next();
			if(Objects.equals(item,"55")){
				i.remove();
			}
		}
	});

	//forEach 循环
	for (String s : list) {
		//
	}
}

或使用



public static void test(List<String> list) throws Exception {
	// 异步方法
	ThreadPoolUtil.getInstance().execute(() -> {
		for (int i =0 ; i < list.size(); i++) {
			String s = list.get(i);
			if(Objects.equals(item,"55")){
				list.remove(s);
			}
		}
	});

	//forEach 循环
	for (String s : list) {
		//
	}
}

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值