private void recycleEx(LevelChangeDO levelChangeRequestDO, LevelPO currentLevelPO) {
BigDecimal deductExperienceAmt = currentLevelPO.getDeductExperienceAmt();
List<LevelTransPO> update = Lists.newArrayList();
List<LevelTransPO> delete = Lists.newArrayList();
// 构造对象,记录这次明细
LevelTransPO levelTransDetailPO = levelTransDetailPOS.get(0);
levelTransPO.setCreatedAt(null);
levelTransPO.setId(null);
levelTransPO.setBizNo(。。。);
levelTransPO.setBizType(。。。);
levelTransPO.setTotalAmt(currentLevelPO.getDeductExperienceAmt());
levelTransPO.setRestAmt(。。。);
levelTransPO.setOperatorDict(。。。);
levelTransPO.setReason(。。。);
// 取出所有的正向值,进行抵扣本次扣减值
for (LevelTransDetailPO levelTransDetail : levelTransDetailPOS) {
if (levelTransDetail.getTotalAmt().longValue() > deductExperienceAmt.longValue()) {
levelTransDetail.setRestAmt(levelTransDetail.getTotalAmt().subtract(deductExperienceAmt));
levelTransDetail.setReturnAmt(deductExperienceAmt);
update.add(levelTransDetail);
break;
} else {
deductExperienceAmt = deductExperienceAmt.subtract(levelTransDetail.getTotalAmt());
delete.add(levelTransDetail);
}
}
// 修改正向抵扣的
levelTransDetailMapper.update(update);
levelTransDetailMapper.delete(delete);
// 创建本次明细
levelTransDetailMapper.create(levelTransPO);
}
大家好,我是反卷猫,一个杭漂的Java程序员。今天给大家带来的是一期关于Java数组产生的小bug,话不多说我们直接进入正题。
需求描述
用户由于违反的社区的相关条例,被扣除对应的成长值。
成长值:用户进行升级的重要依据,比如用户达到1000成长值就升级为白银等级,2000成长值升级为黄金等级。
既然需要扣除成长值,那我们肯定需要获取正向的成长值记录吧
成长值记录:为了统计用户何时获取(扣减)的成长值,故添加明细表,用来记录用户成长值的变化,总的成长值 = sum(正向可用成长值之和)
获取到了正向的成长值记录后,就需要遍历记录(毕竟可能一条不够减情况,就需要获取多条),直到待扣减的余额为0。
随后能我们就需要修改正向记录的可用额度(levelTransDetailMapper.update(修改的记录)),
同时将本次扣减的额度记录到明细中(levelTransDetailMapper.create(levelTransPO))。
bug出现
// 构造对象,记录这次明细
LevelTransPO levelTransDetailPO = levelTransDetailPOS.get(0);
由于需要创建明细,该模型包含字段又比较多,bug猫呢就准备偷个小懒,直接去除集合中的第一个(前面有判断集合是否为空哈)进行复用,同时还行这个对象中set了一些值。
家人们可以猜猜会出现什么问题哈,请把会出现的问题打在评论区
导致的问题
1、遍历一次就扣减完了???(levelTransPO.setTotalAmt(currentLevelPO.getDeductExperienceAmt());)
2、为啥create的时候报主键重复错误???
发现原因
// 构造对象,记录这次明细
LevelTransPO levelTransDetailPO = levelTransDetailPOS.get(0);
levelTransDetailPOS为List集合,底层是基于数组进行实现的。因为集合中的对象是引用类型,levelTransDetailPO是集合中第一个对象的引用,通过修改levelTransDetailPO的属性值,就相当于修改了集合中第一个对象的属性值。
那第二个又是如何产生的呢,是因为取出来的levelTransDetailPO存在id,导致主键冲突了。
解决方案
1、老老实实构造个新的对象
2、使用深复制,将levelTransDetailPOS.get(0)进行深拷贝,但是记得将id set 为null,防止创建的时候导致id冲突(其他唯一字段同样需要重新赋值)。
好嘞,本期分享的bug就到这结束了,欢迎家人们在评论区讨论你们在工作或学习中遇到的bug吧!我们下期再见!