定义ArrayList为全部变量引发的错误
@Transactional public ApiResult sendCoupon(CouponRequest couponRequest){ ApiResult apiResult=new ApiResult(); if(StringUtils.isBlank(couponRequest.getProgramToken())){ apiResult.fail(ErrCode.PROGRAMTOKEN_NOT_NULL.getIndex(), ErrCode.PROGRAMTOKEN_NOT_NULL.getName()); return apiResult; } if(StringUtils.isBlank(couponRequest.getUserIds())){ apiResult.fail(ErrCode.NOT_LESS_UPDATE_SCORE_.getIndex(), ErrCode.NOT_LESS_UPDATE_SCORE_.getName()); return apiResult; } MiniProgram miniProgram = miniProgramService.queryByToken(couponRequest.getProgramToken()); Optional.ofNullable(miniProgram).orElseThrow(() -> new MiniException(ErrCode.PROGRAM_NOT_EXISTS)); Optional.ofNullable(couponRequest.getId()).orElseThrow(()->new CouponException(ErrCode.PRIMARY_ID_NOT_NULL)); Coupon entity=couponService.getCoupon(couponRequest.getId()); String[] str=couponRequest.getUserIds().split(","); UserCoupon userCoupon=null; UserCouponDetail userCouponDetail=null; UserCouponItemRelation userCouponItemRelation=null; UserCouponShopRelation userCouponShopRelation=null; List<UserCouponItemRelation> userCouponItemRelationList=new ArrayList<>(); List<UserCouponShopRelation> userCouponShopRelationList=null; for(int i=0;i<str.length;i++){//将优惠券派发给多个会员 //关联会员优惠券表 userCoupon=new UserCoupon(); userCoupon.setUserInfoId(Long.parseLong(str[i])); userCoupon.setUseStatus(Boolean.FALSE);//未使用 userCoupon.setCouponId(entity.getId()); userCoupon.setSouce(CouponSouceEnum.BUSINESS_DISTRIBUTION.getName());//商家派发 userCoupon.setCreateTime(new Date()); userCoupon.setUpdateTime(new Date()); //保存获取主键id userCouponService.insert(userCoupon); //关联会员优惠券明细表 userCouponDetail=new UserCouponDetail(); userCouponDetail.setCouponId(entity.getId()); userCouponDetail.setUserCouponsId(userCoupon.getId()); userCouponDetail.setCouponName(entity.getName());//优惠券名称 userCouponDetail.setCouponType(entity.getCouponType());//优惠券类型 userCouponDetail.setDeduct(entity.getDeduct());//抵扣金额 userCouponDetail.setDiscount(entity.getDiscount());//折扣比率 userCouponDetail.setLowerConsumerAmount(entity.getLowerConsumerAmount());//最低消费 userCouponDetail.setUseRange(entity.getUseRange());//使用范围 userCouponDetail.setValidStartDate(entity.getValidStartDate());//有效期开始时间 userCouponDetail.setValidEndDate(entity.getValidEndDate());//有效期结束时间 userCouponDetail.setRemark(entity.getRemark()); userCouponDetailService.addUserCouponDetail(userCouponDetail); if(entity.getUseRange().equals(UseRangeEnum.PART.getName())){ //关联会员优惠券项目表 List<CouponItemRelation> couponItemRelationList=couponItemRelationService.queryByCouponId(entity.getId()); //userCouponItemRelationList=new ArrayList<>(); for(CouponItemRelation couponItemRelation:couponItemRelationList){ userCouponItemRelation=new UserCouponItemRelation(); userCouponItemRelation.setCouponId(entity.getId()); userCouponItemRelation.setUserCouponsId(userCoupon.getId()); userCouponItemRelation.setValueId(couponItemRelation.getValueId()); userCouponItemRelation.setItemType(couponItemRelation.getItemType()); userCouponItemRelation.setItemTitle(ServiceTypeEnum.getValue(couponItemRelation.getItemType()));//关联项目名称 userCouponItemRelation.setValid(true); userCouponItemRelation.setCreateTime(new Date()); userCouponItemRelation.setUpdateTime(new Date()); userCouponItemRelationList.add(userCouponItemRelation); } userCouponItemRelationService.batchAddUserCouponItemRelation(userCouponItemRelationList); } //关联会员优惠券门店表 List<CouponShopRelation> couponShopRelationList=couponShopRelationService.queryByCouponId(entity.getId()); userCouponShopRelationList=new ArrayList<>(); for(CouponShopRelation couponShopRelation:couponShopRelationList){ userCouponShopRelation=new UserCouponShopRelation(); userCouponShopRelation.setCouponId(entity.getId()); userCouponShopRelation.setUserCouponsId(userCoupon.getId()); userCouponShopRelation.setShopId(couponShopRelation.getShopId()); userCouponShopRelation.setValid(true); userCouponShopRelationList.add(userCouponShopRelation); } userCouponShopRelationService.batchAddUserCouponShopRelation(userCouponShopRelationList); } entity.setRemainAmount(entity.getRemainAmount()-str.length); couponService.updateCoupon(entity); apiResult.succ(entity); return apiResult; }
定义userCouponItemRelationList为全局变量的时候,使用for循环遍历。第一次循环,userCouponItemRelationList添加了五个元素,第二次循环添加了三个,第二次的时候,userCouponItemRelationList元素为8
一共保存了5+(5+3)=13条记录
我预期是5+3=8
出现问题的根本原因就是userCouponItemRelationList每次循环一直追加
解决方案:
在外部申明:
List<UserCouponItemRelation> userCouponItemRelationList=null;
在每次循环的时候分配内存
List<UserCouponItemRelation> userCouponItemRelationList=new ArrayList<>();
或:
使用ArrayList.clear() 每次循环清空、
public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }
扩展:
对象的声明放在栈内存,在实例化对象的时候,会在堆内存开辟一个内存,然后把这个内存的地址交给对象。这个就是对象的声明和实例化过程
一)关于使用ArrayList存储全局变量
代码如下:
public static void main(String[] args){
Demo demo=new Demo(); //这里声明一个全局变量
List<Demo> demoList=new ArrayList<Demo>(); //声明一个arraylist存储对象
for(int i=0;i<3;i++){
demo.setId(i);
demoList.add(demo);
System.out.println(demo);
System.out.println("demoList.get(i):"+demoList.get(i).getId());
}
for(int i=0;i<3;i++){
System.out.println(demoList.get(i).getId()); //用循环打印
}
}
输出结果:
Demo [id=0]
demoList.get(i):0
Demo [id=1]
demoList.get(i):1
Demo [id=2]
demoList.get(i):2
2
2
2
问:为什么在循环输出时候提取list是相同?
个人总结:
(1)List里面虽然有3个元素,但是元素的对象指向的地址都是同一个内存地址。
(2)你只new一次,但是只为demo分配一个地址,但是每次都是操作这个demo,第一个循环。
(3)另外,因为list是允许元素重复的,所以,你同一个对象可以加N次,另一个集合set是不允许元素重复。
元素重复的意思是,内存地址一样
(4)最后一次则添加id为2,则覆盖之前的id,arraylist则存储最后一个对象的值。
二)使用arraylist存储局部变量
对于上边的程序,把声明放到for循环里面时候,则是不同的指向地址。
public static void main(String[] args){
//Demo demo=new Demo(); //注释掉,换到for循环里面
List<Demo> demoList=new ArrayList<Demo>();
for(int i=0;i<3;i++){
Demo demo=new Demo();
demo.setId(i);
demoList.add(demo);
System.out.println(demo);
System.out.println("demoList.get(i):"+demoList.get(i).getId());
}
for(int i=0;i<3;i++){
System.out.println(demoList.get(i).getId());
}
}
运行结果:
Demo [id=0]
demoList.get(i):0
Demo [id=1]
demoList.get(i):1
Demo [id=2]
demoList.get(i):2
0
1
2