反射处理两对象每个同名BigDecimal类型的值累加

背景

当需要将两个对象中多个同名的属性进行相加时,往往会出现如下代码段

User target = new User();
User u1 = new User();
u1.setJanuaryAmount(BigDecimal.valueOf(3.5));
u1.setFebruaryAmount(BigDecimal.valueOf(1.5));

User u2 = new User();
u2.setJanuaryAmount(BigDecimal.valueOf(5.2));
u2.setFebruaryAmount(BigDecimal.valueOf(22.5));

// 将u1和u2两对象同名的属性进行相加
target.setJanuaryAmount(u1.getJanuaryAmount().add(u2.getJanuaryAmount()));
target.setFebruaryAmount(u1.getFebruaryAmount().add(u2.getFebruaryAmount()));

当需要相加的属性过多时,将会出现一个属性相加则多一行target.setXXX()代码。

此时手写set方法将变得不再优雅。


 创建一个简易实体User,包含Bigdecimal类型用于运算

public class User {
    private String username;

    private String ggg;

    private BigDecimal januaryAmount;

    private BigDecimal augustAmount;

    private BigDecimal februaryAmount;

    ...
    
    getter() && setter() 
}

 创建反射处理工具类reflexToAddFieldValue

private static void reflexToAddFieldValue(User source, User target){
        try {
            // 分别获取两对象的字段列表
            Field[] sFields = source.getClass().getDeclaredFields();
            Field[] tFields = target.getClass().getDeclaredFields();
            for(Field sField:sFields){
                // 若字段不为BigDecimal类型,则直接过滤
                if(!sField.getType().getName().contains("BigDecimal")){
                    continue;
                }
                String sName = sField.getName();
                for(Field tField:tFields){
                    // 若字段不为BigDecimal类型,则直接过滤
                    if(!tField.getType().getName().contains("BigDecimal")){
                        continue;
                    }
                    String tName = tField.getName();
                    // 两不同对象的字段类型相同时,则对数据进行相加操作
                    if(sName.equals(tName)){
                        // 关闭两字段的安全检查
                        sField.setAccessible(true);
                        tField.setAccessible(true);

                        BigDecimal sDecimal = (BigDecimal)sField.get(source);
                        BigDecimal tDecimal = (BigDecimal)tField.get(target);
                        BigDecimal finalDecimal = null;
                        // 若均存在,则两者值相加;仅一方存在则直接赋予
                        if(sDecimal!=null && tDecimal!=null){
                            finalDecimal = sDecimal.add(tDecimal);
                        } else if(sDecimal!=null && tDecimal==null){
                            finalDecimal = sDecimal;
                        } else if (sDecimal==null && tDecimal!=null){
                            finalDecimal = tDecimal;
                        } else {
                            sField.setAccessible(false);
                            tField.setAccessible(false);
                            continue;
                        }
                        // 将计算出的值重新赋予目标对象进行返回
                        tField.set(target, finalDecimal);
                        sField.setAccessible(false);
                        tField.setAccessible(false);
                    }
                }
            }
        } catch (Exception e){
            LOGGER.error("程序处理异常", e);
        }
    }

使用main方法测试

public static void main(String[] args) {
        try{
            List<User> list = new ArrayList<>();
            User u1 = new User();
            u1.setUsername("shanghai");
            u1.setGgg("阳光");
            u1.setJanuaryAmount(BigDecimal.valueOf(3.5));

            User u2 = new User();
            u2.setUsername("shanghai");
            u2.setGgg("沙滩");
            u2.setAugustAmount(BigDecimal.valueOf(3.5));

            User u3 = new User();
            u3.setUsername("shumin");
            u3.setGgg("海浪");
            u3.setJanuaryAmount(BigDecimal.valueOf(4));

            User u4 = new User();
            u4.setUsername("shumin");
            u4.setGgg("仙人掌");
            u4.setJanuaryAmount(BigDecimal.valueOf(3.5));

            User u5 = new User();
            u5.setUsername("aaa");
            u5.setGgg("老船长");
            u5.setJanuaryAmount(BigDecimal.valueOf(3.5));
            u5.setFebruaryAmount(BigDecimal.valueOf(2));

            User u6 = new User();
            u6.setUsername("aaa");
            u6.setGgg("小孩");
            u6.setJanuaryAmount(BigDecimal.valueOf(3.5));
            u6.setFebruaryAmount(BigDecimal.valueOf(888));

            list.add(u1);
            list.add(u2);
            list.add(u3);
            list.add(u4);
            list.add(u5);
            list.add(u6);

            List<User> targetVOList = new ArrayList<>();
            // 按属性username分组
            Map<String, List<User>> map = list.stream().collect(Collectors.groupingBy(User::getUsername));
            for(String username:map.keySet()){
                List<User> mapByUsernameList = map.get(username);
                // 设置目标对象
                User targetVO = new User();
                StringBuilder nameBuilder = new StringBuilder();
                for(int i=0;i<mapByUsernameList.size();i++){
                    User sourceVO = mapByUsernameList.get(i);
                    // 手动合并特定属性值
                    nameBuilder.append(sourceVO.getGgg()).append(",");
                    if(i==0){
                        // 初始化目标对象
                        BeanUtils.copyProperties(sourceVO, targetVO);
                        continue;
                    }
                    // 反射处理两对象每个数据类型值相加
                    reflexToAddFieldValue(sourceVO, targetVO);
                }
                nameBuilder.delete(nameBuilder.length()-1, nameBuilder.length());
                targetVO.setGgg(nameBuilder.toString());
                targetVOList.add(targetVO);
            }

            for(User target:targetVOList){
                LOGGER.info("{}", target);
            }
        } catch(Exception e) {
            LOGGER.error("异常【{}】", e);
        }
    }

控制台输出

10:25:08.261 [main] INFO cn.gdxiash.consumer.test.Test01 - User{username='aaa', ggg='老船长,小孩', januaryAmount=7.0, februaryAmount=890, augustAmount=null}
10:25:08.267 [main] INFO cn.gdxiash.consumer.test.Test01 - User{username='shanghai', ggg='阳光,沙滩', januaryAmount=3.5, februaryAmount=null,augustAmount=3.5}
10:25:08.267 [main] INFO cn.gdxiash.consumer.test.Test01 - User{username='shumin', ggg='海浪,仙人掌', januaryAmount=7.5, februaryAmount=null, augustAmount=null}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值