定义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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值