关于报错java.util.ConcurrentModificationException: null的源码分析和解决

一般有这种问题,方法中至少会有List或者Map下的至少两个子类,有可能参数类型相同,也有可能不同都有可能触发这个问题!其主要原因是使用了ArrayList进行删除操作或者使用iterator遍历集合的同时对集合进行修改都有可能会出现这个问题

ArrayList属于List下的子类

需要区分的是List在java中有两个属于两个不同的包,这里说的是Util包下的List!两个类一个是接口一个是Class类(基础知识了吧算是)

针对此问题的ArrayList源码解析https://blog.csdn.net/qq_43705131/article/details/122607384

问题截图及源码触发部分代码

业务问题代码

不管泛型使用的是同种参数还是不同参数都要注意这个问题

场景复现

业务场景:

需要一个接口返回一个List对象,但是在List中需要调用另一个接口并将该接口的返回结果插入List中(如上图代码注释所写)

这时候类型的兼容性问题就出现了

代码场景:

首先:调用接口返回一个集合,需要集合中的全部数据及拿到集合中的ID

List<Map<String, List>> periodicLQ = periodicObservationMapper.periodicLQ(pointId,dir, lineNo, startDate, endDate);

用于调用另一个接口查询该ID下的全部值并且赋到一个List中用于返回

List structureDetailInfo = structureDetailInfoMapper.selectByPavementStructureInfoIds(ids);

代码实现:(问题复现)

这样写在List structureDetailInfo = structureDetailInfoMapper.selectByPavementStructureInfoIds(ids);

java 复制代码
{

		//查询结构内     基本数据及  联合数据 ,返回统计结果     拿到structure_info 的 ID拿到结构数据将此以数组返回到VO
		List<Map<String, List<StructureDetailInfoPO>>> periodicLQ = periodicObservationMapper.periodicLQ(pointId,dir, lineNo, startDate, endDate);

		Map<String, List<StructureDetailInfoPO>> structureInfo = new HashMap<>();

		//用于存储接口获取到的所有id值
		List<Long> ids = new ArrayList<>();
		for (Map<String, List<StructureDetailInfoPO>> item: periodicLQ) {

			if (!item.isEmpty()){
			Long id = Long.valueOf(String.valueOf(item.get("id")));
			ids.add(id);
				for (int i = 0;i <= item.size();i++){

			
					List<StructureDetailInfoPO> structureDetailInfo = structureDetailInfoMapper.selectByPavementStructureInfoIds(ids);
					structureInfo.put("structureInfo",structureDetailInfo);
					//System.out.println(" structure detail info size : " + structureDetailInfo);
					
					//resultMap.add(structureInfo);
				}
					result.add(item);
					//result.add(structureInfo);
					//break;
			}
			System.out.println(" result size : " + result);
		}

		return result;
	}

解决方案-->避免修改ArrayList或者引用的其他List类和Map中的子类

创建一个名为 resultMap 的临时列表,并在循环中将结构信息添加到该列表中。最后,我们返回 resultMap 列表,而不是修改 result 列表用于返回。这就能够解决 ConcurrentModificationException 异常的问题,因为这样就创建了一个中间变量用来存储结果,避免修改了原来的result列表(List)

java 复制代码
{

		//查询结构内     基本数据及  联合数据 ,返回统计结果     拿到structure_info 的 ID拿到结构数据将此以数组返回到VO
		List<Map<String, List<StructureDetailInfoPO>>> periodicLQ = periodicObservationMapper.periodicLQ(pointId,dir, lineNo, startDate, endDate);

		List<Map<String, List<StructureDetailInfoPO>>> resultMap = new ArrayList<>();
		Map<String, List<StructureDetailInfoPO>> structureInfo = new HashMap<>();

		//用于存储接口获取到的所有id值
		List<Long> ids = new ArrayList<>();
		for (Map<String, List<StructureDetailInfoPO>> item: periodicLQ) {

			if (!item.isEmpty()){
			Long id = Long.valueOf(String.valueOf(item.get("id")));
			ids.add(id);
				for (int i = 0;i <= item.size();i++){

					if (i == item.size()){

					List<StructureDetailInfoPO> structureDetailInfo = structureDetailInfoMapper.selectByPavementStructureInfoIds(ids);
					structureInfo.put("structureInfo",structureDetailInfo);
					//System.out.println(" structure detail info size : " + structureDetailInfo);
					}else {
					    continue;
					}

					//resultMap.add(structureInfo);
				}
					resultMap.add(item);
					resultMap.add(structureInfo);
					//break;
			}
			System.out.println(" result size : " + resultMap);
		}

		return resultMap;
	}

:w最后总结:

代码中有

Long id = Long.valueOf(String.valueOf(item.get("id")));

在写这个的时候,一开始用了toString,编译不报错但运行有错,也建议大家使用这种包围的方法取代.***的方法(这种问题一定会随着jdk的不断更新有所改正)

此外在对断点进行一步步跟踪到源代码时发现的问题触代码如下

如图所示我们在读过SQLsession等常规源码后发现代码执行到了此类中,并确认了SQL是否执行正确

在左下角即为控制程序执行的断点按钮,可以手动点击||,这样resume按钮就会变绿变亮

问题触发代码:↓↓↓

相关推荐
海上彼尚20 分钟前
Go之路 - 7.go的结构体
开发语言·后端·golang
源代码•宸5 小时前
分布式缓存-GO(分布式算法之一致性哈希、缓存对外服务化)
开发语言·经验分享·分布式·后端·算法·缓存·golang
云和数据.ChenGuang6 小时前
PHP-FPM返回的File not found.”的本质
开发语言·php·运维工程师·运维技术
It's now6 小时前
Spring AI 基础开发流程
java·人工智能·后端·spring
cxh_陈6 小时前
线程的状态,以及和锁有什么关系
java·线程·线程的状态·线程和锁
计算机毕设VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue图书商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
R.lin6 小时前
Java 8日期时间API完全指南
java·开发语言·python
毕设源码-赖学姐6 小时前
【开题答辩全过程】以 高校教学质量监控平台为例,包含答辩的问题和答案
java·eclipse
高山上有一只小老虎6 小时前
翻之矩阵中的行
java·算法
激动的兔子6 小时前
Windows系统的回收站文件加载慢无法删除该如何解决
windows