浅析Java中for循环里对list进行add操作踩坑
一、结论
先说结论:使用 for 循环循环一个list,并在for循环中将某对象或者用于承载数据的list 添加add进另外一个list时,该对象或用于承载数据的 list 必须要在for循环内创建。若在for循环外创建,则 add 进的数据都会变成最后一次循环添加的数据。
List<ManHourSummaryVo> mhSummaryVoList = manHourSummaryMapper.selectHoursByNo(EmployeeNoMap);
calculateAnnualLeave(mhSummaryVoList);
if(mhSummaryVoList.size()>0){
for(int i = 0;i < mhSummaryVoList.size(); i++){
ManHourSummaryVo mhSummaryVo = mhSummaryVoList.get(i);
List<String> contentList = new LinkedList<String>();
if(null != mhSummaryVo){
contentList.add(nullToStr(mhSummaryVo.getName()));
contentList.add(null == mhSummaryVo.getEmployeeNo() ? "" : mhSummaryVo.getEmployeeNo().toString());
......
}
// 存入工作表内容
titleAndContList.add(contentList);
}
}
其中 List<String> contentList = new LinkedList<String>(); 必须在 for 循环内部创建,如果是在 for 循环外部创建,则 add 进的数据都会是最后一次循环添加的数据。
以上代码遍历 mhSummaryVoList,然后创建 contentList 用于承载 mhSummaryVoList 里元素的数据,然后再把 contentList 添加到 titleAndContList。因此 contentList 必须在 for 循环内部被创建。
使用for循环给list赋值,结果发现得到的list中的元素值全都变成了最后一个元素的值,经过查资料才知道 list 在add时,每次保留一个它的引用,所以在for循环外面new list 的元素,最后得到的list里面全都成了最后一次的值。因此每循环一次,就要new 一次list中的元素对象。
二、问题解析
1、问题现象:分别在 for 循环内外new一个对象,然后在循环中将对象加入集合中,两种方法产生的结果不同。
(1)在for循环内new一个对象,并添加进list中,与添加数值的结果没有差别。
(2)在for循环外new一个对象,并添加进list中,无论循环多少次,最终整个list中的结果都会是最后一次赋值为对象的结果。
2、原因:
在创建List时,指定了引用对象House作用泛型,list.add()在添加对象时,添加的是它的引用,而在循环体外new一个对象,在循环体内赋值,则对象House引用不变,数值改变,因引用不变,最终赋值结果指向引用,list 集合中都是最后一次赋值的结果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律