怎样正确遍历删除ArrayList集合元素

作为一个平凡的码农,相信同道中人对集合这个词都不陌生,日常工作中我们经常会涉及到集合的各种操作,本篇文章抛砖引玉总结下ArrayList遍历时删除集合元素踩得坑,以及解决问题的集中方法,供大家参考!

一、事情起因

某天下午正犯困的时间点,领导在工作群里发了一张代码图,问大家这样的写法是否有问题,第一反应是不是自己的bug?

        List<Map<String,Object>> list = new ArrayList<>();
		Map<String,Object> m = new HashMap<String,Object>();
		m.put("a1", 12);
		Map<String,Object> m1 = new HashMap<String,Object>();
		m1.put("a1", 11);
		Map<String,Object> m2 = new HashMap<String,Object>();
		m2.put("a1", 11);
		list.add(m);
		list.add(m1);
		list.add(m2);
		System.out.println("去重前:" + JSON.toJSON(list));
		//去重
		List<String> sids = new ArrayList<>();
		for(Map<String,Object> map : list){
			String ret = String.valueOf(map.get("a1"));
			if(sids.contains(ret)){
				list.remove(map);
			}
			sids.add(ret);
		}

大家立马精神起来认真看了下这段代码,纷纷发表自己见解,但毕竟有理有据才更有说服力,于是开始亲测:
在这里插入图片描述

二、究其因果

代码中直接使用增强for循环,判断条件成立时删除元素,此方法在遍历时会抛出ConcurrentmodificationException异常,为了查清楚异常原因,查看源码remove方法中调用fastRemove(基于JDK1.8)
在这里插入图片描述
fastRemove方法中显示modCount在操作时会自增加1:
在这里插入图片描述
移除元素后遍历继续执行next():
在这里插入图片描述
checkForComodification()方法中比较两个参数是否相等,初始值是一样的,移除元素后modCount+1,会触发异常:
在这里插入图片描述

三、探索方案

我们日常用到遍历集合最多的方法有以下几种:
1、使用增强for循环,经测试报异常——不可用
代码:
在这里插入图片描述
结果:
在这里插入图片描述
2、使用普通for循环(正序),经测试去重结果不准确——不可用
代码:
在这里插入图片描述
结果:
在这里插入图片描述
3、使用迭代器自身的remove方法,经测试——可用
代码:
在这里插入图片描述
结果:
在这里插入图片描述
4、使用通for循环(倒序),经测试——可用
代码:
在这里插入图片描述
结果:
在这里插入图片描述
5、使用jdk1.8的Stream流操作,经测试——可用
代码:
在这里插入图片描述
结果:
在这里插入图片描述
6、使用java.util.concurrent下的CopyOnWriteArrayList替代ArrayList,经测试——可用
代码:
在这里插入图片描述
结果:
在这里插入图片描述
总结:经过测试验证,我们发现3、4、5、6几种方法是可以实现我们的去重目的的,测试过程中可能存在其他偶然因素造成结果不准确,欢迎大家验证并提出建议和见解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值