汇总数据工具类(反射、注解)

通过反射+注解,计算集合中的数据,并生成汇总结果

运行结果

实体类

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;

/**
 * TODO 类注释
 *
 * @author shuai
 * @since 2023-03-04
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TestVo {

    @SummaryDesc
    private String desc;

    private int intField1;

    private Integer intField2;

    private BigDecimal bmField1;

    private BigDecimal bmField2;

}

注解

import java.lang.annotation.*;

/**
 * 定义数据汇总的描述字段
 *
 * @author shuai
 * @since 2023-03-04
 */
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SummaryDesc {

}

工具类

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据汇总工具类
 *
 * @author shuai
 * @since 2023-03-04
 */
@Slf4j
public class Utils {

    /**
     * 数据汇总(汇总int、Integer、BigDecimal类型)
     * @param clazz class
     * @param list 数据集合
     * @param <T> T
     * @return 汇总T
     */
    public static <T> T getSum(Class<T> clazz, List<T> list){
        return getSum(clazz,list,null,"合计");
    }

    /**
     * 数据汇总(单一类型)
     * @param clazz class
     * @param list 数据集合
     * @param type 汇总的字段类型 例:BigDecimal.class
     * @param <T> T
     * @return 汇总T
     */
    public static <T> T getSum(Class<T> clazz, List<T> list ,Object type){
        return getSum(clazz, list, type, "合计");
    }

    /**
     * 数据汇总(汇总int、Integer、BigDecimal类型)
     * @param clazz class
     * @param list 数据集合
     * @param <T> T
     * @return 汇总T
     */
    public static <T> T getSum(Class<T> clazz, List<T> list, String var){
        return getSum(clazz, list, null, var);
    }

    /**
     * 数据汇总
     * @param clazz class
     * @param list 数据集合
     * @param type 汇总的字段类型
     * @param var 汇总字段描述
     * @param <T> T
     * @return 汇总T
     */
    public static <T> T getSum(Class<T> clazz, List<T> list,Object type, String var){
        return getSumData(clazz, list, type, var);
    }

    /**
     * 汇总的字段类型
     * @param obj 字段类型
     * @return 类型集合
     */
    private static List<Object> getFieldTypes(Object obj){
        if(null == obj){
            return Arrays.asList(int.class, Integer.class, BigDecimal.class);
        }
        return Collections.singletonList(obj);
    }

    /**
     * 数据汇总
     * @param clazz class
     * @param list 数据集合
     * @param type 汇总的字段类型
     * @param var 汇总字段描述
     * @param <T> T
     * @return 汇总T
     */
    private static <T> T getSumData(Class<T> clazz, List<T> list, Object type, String var){
        //汇总的字段类型
        List<Object> types = getFieldTypes(type);
        //获取class所有属性字段
        Field[] fields = ReflectUtil.getFields(clazz);
        //过滤出需要计算合计的字段
        List<Field> fieldList = Arrays.stream(fields).filter(field -> types.contains(field.getType())).collect(Collectors.toList());
        //汇总数据map
        Map<String,Object> map = Maps.newHashMapWithExpectedSize(fieldList.size());
        fieldList.forEach(field -> {
            //开启访问权限
            field.setAccessible(true);
            list.stream().forEach(item->{
                try {
                    if(field.getType() == int.class || field.getType() == Integer.class){
                        Integer now = ObjectUtil.isNull(field.get(item)) ? 0 : (Integer) field.get(item);
                        Integer oldSum = ObjectUtil.isNull(map.get(field.getName())) ? 0 : (Integer) map.get(field.getName());
                        map.put(field.getName(), now + oldSum);
                    }
                    if(field.getType() == BigDecimal.class){
                        BigDecimal now = ObjectUtil.isNull(field.get(item)) ? BigDecimal.ZERO : (BigDecimal) field.get(item);
                        BigDecimal oldSum = ObjectUtil.isNull(map.get(field.getName())) ? BigDecimal.ZERO : (BigDecimal) map.get(field.getName());
                        map.put(field.getName(), now.add(oldSum));
                    }
                } catch (IllegalAccessException e) {
                    log.error(e.getMessage());
                }
            });
        });
        //实例化对象
        T t = ReflectUtil.newInstance(clazz);
        Arrays.stream(fields).forEach(field->{
            //添加描述
            SummaryDesc summaryDesc = field.getAnnotation(SummaryDesc.class);
            if(ObjectUtil.isNotEmpty(summaryDesc)){
                ReflectUtil.invoke(t,StrUtil.addPrefixIfNot(StrUtil.upperFirst(field.getName()),"set"),var);
                return;
            }
            if(ObjectUtil.isNotEmpty(map.get(field.getName()))){
                ReflectUtil.invoke(t,StrUtil.addPrefixIfNot(StrUtil.upperFirst(field.getName()),"set"),map.get(field.getName()));
            }
        });
        return t;
    }
}

测试类

import cn.hutool.core.collection.CollUtil;

import java.math.BigDecimal;
import java.util.List;

/**
 * TODO 类注释
 *
 * @author shuai
 * @since 2023-03-04
 */
public class Test {

    private static List<TestVo> setTestVo(){
        List<TestVo> vos = CollUtil.newArrayList();
        for (int i = 1; i < 3; i++) {
            TestVo vo = TestVo.builder().desc("test"+i).intField1(i).intField2(i*2)
                    .bmField1(BigDecimal.ONE.multiply(new BigDecimal(i)))
                    .bmField2(BigDecimal.ONE.multiply(new BigDecimal(i*2))).build();
            vos.add(vo);
        }
        return vos;
    }

    public static void main(String[] args) {
        List<TestVo> testVos = setTestVo();
        testVos.add(Utils.getSum(TestVo.class,testVos));
        testVos.forEach(System.out::println);
    }

}

运行结果

1.汇总数据

Utils.getSum(TestVo.class,testVos)

在这里插入图片描述

2.汇总某种字段类型的数据

Utils.getSum(TestVo.class,testVos,Integer.class)

在这里插入图片描述

3.汇总某种字段类型数据,自定义字段描述

Utils.getSum(TestVo.class,testVos,Integer.class,“测试汇总数据”)

在这里插入图片描述

4.汇总所有类型数据,自定义字段描述

Utils.getSum(TestVo.class,testVos,“测试汇总数据”)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
糊涂工具是一个功能强大的工具类库,它为我们的开发过程提供了许多便利。其中,它提供了execl导入注解的功能,使得我们可以轻松地将数据从execl文件中导入到我们的程序中。 通过使用糊涂工具提供的注解,我们可以在实体类的属性上添加注解,定义该属性与execl文件中的列的映射关系。这样一来,我们只需要一行代码即可将execl文件中的数据与实体类对象进行绑定。 糊涂工具使用了反射机制,根据注解的配置信息,自动完成了数据导入的过程。它能够根据execl文件的列名,自动匹配到对应的实体类属性,并将数据赋值给相应的属性。同时,它还支持一些常见的数据类型转换,比如将字符串类型自动转换为整数、浮点数等类型。 除了基本的数据导入功能,糊涂工具还提供了一些额外的特性,比如数据校验、异常处理等。通过在注解中添加一些配置参数,可以实现对导入数据的校验,确保导入的数据符合预期的格式和要求。同时,它还能够对导入数据过程中出现的异常进行处理,比如数据类型转换异常、空指针异常等。 总之,糊涂工具类的execl导入注解功能能够极大地简化我们的开发工作,提高开发效率。它通过注解配置,自动完成数据导入的过程,支持数据类型转换和数据校验等功能,为我们的开发带来了许多便利。无论是小型项目还是大型项目,糊涂工具都是一个值得使用的工具类库。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值