Java for循环遍历Tariff仅命中单条记录、重复输出同值问题排查
循环setComp异常问题诊断
现存问题根因
- 你在条件判断块末尾写了
break关键字:该语法会在命中第一条符合Type=A且discSum > minSum的记录后,直接终止整个for循环,不会继续遍历列表剩余条目。你控制台反复打印6组相同的0.15、0.22270,是因为这段带break的循环本身被外层逻辑重复调用了6次,每次调用都从列表头开始遍历,命中第二条DiscSum为0.22270的记录就执行打印、跳出,所以输出内容完全一致。 - 所有Tariff记录的Comp值被同步修改,是因为列表存储的对象存在共享引用问题:你初始化Tariff列表时,大概率是把同一个Tariff实例重复add进了列表,所有条目实际指向堆内存里的同一个对象,此时调用任意一个条目的
setComp方法,修改的都是共享对象的属性,自然会表现为「改一条全表生效」。
修正方案
- 移除条件块内的
break语句,如果你的需求是仅给第一条符合条件的记录设置Comp,其余符合条件的记录不处理,新增布尔标记位控制单次执行即可,不要用break直接打断循环导致外层重复调用时反复命中同一条记录;如果需求是给所有符合条件的记录分别设置Comp,删掉break后直接遍历即可。 - 排查Tariff列表的初始化逻辑,确保每次add进列表的都是单独
new出来的独立Tariff实例,禁止同一对象重复加入列表。
参考修正代码
// 标记是否已完成首条符合条件记录的Comp设置,避免重复赋值 boolean compSetted = false; // 变量名首字母小写符合Java编码规范 for (int index = 0; index < tariff.size(); index++) { Tariff current = tariff.get(index); // 字符串常量放前面可避免空指针 if ("A".equals(current.getType()) && minSum != null && current.getDiscSum().compareTo(minSum) > 0) { // 仅首次命中时执行打印和赋值 if (!compSetted) { System.out.println(minSum); System.out.println(current.getDiscSum()); BigDecimal calcResult = current.getPrice() .subtract(current.getPrice().subtract(minSum).min(maxSum)); current.setComp(calcResult); compSetted = true; } } }
补充说明:修正后如果需要遍历所有条目做其他逻辑处理,可以在首次命中赋值后不跳出循环,继续完成剩余条目的遍历,不会再出现反复打印同一值、所有记录Comp被同步修改的问题。
内容的提问来源于stack exchange,提问作者TtT
相关产品推荐
相关产品推荐

