Java里如何优雅的合计多列

Java里如何优雅的合计多列
相信开发朋友们都有碰到一个list对象需要对其中的多列进行不同维度的计算统计,最后返回成一条数据。
以往的做法可能是对这个list对象进行循环,在循环外层定义对象和几个变量接收计算然后set到对象里面。又或者是使用stream流的sum方法计算成一个个值set到对象里。
今天介绍两种方式
方式1:stream流的reduce方法

package com.example.demo.entity;

import cn.hutool.core.util.NumberUtil;
import com.example.demo.annotation.Sum;
import com.example.demo.util.PolymerizationUtil;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

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

/**
 * @author tangsen
 * @since 2023/12/29 14:27
 **/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Compute {

     @Sum
     private BigDecimal fee;
     @Sum
     private Integer count;

     /**
      * 初始化一个空对象方便累加
      */
     public static final Compute EMPTY = new Compute(new BigDecimal("0"),0);

     /**
      * 计算 其他类型自己拓展
      * @param compute1 对象1
      * @param compute2 对象2
      * @return 合计对象
      */
     public static Compute sum(Compute compute1,Compute compute2){
          EMPTY.setFee(NumberUtil.add(compute1.getFee(),compute2.getFee()));
          EMPTY.setCount(compute1.getCount() + compute2.getCount());
          return EMPTY;
     }


     public static List<Compute> getList(){
          List<Compute> computeList = Lists.newArrayList();
          Compute compute1 = new Compute(new BigDecimal("11.11"),1);
          Compute compute2 = new Compute(new BigDecimal("22.22"),2);
          Compute compute3 = new Compute(new BigDecimal("33.33"),3);
          computeList.add(compute1); computeList.add(compute2); computeList.add(compute3);
          return computeList;
     }

     public static void main(String[] args) {
          List<Compute> computeList = getList();
          Compute reduce = computeList.stream().reduce(Compute.EMPTY, Compute::sum);
          System.out.println(reduce);
     }
}

执行结果
在这里插入图片描述
方式2:使用注解+反射
自定义注解

package com.example.demo.annotation;

import java.lang.annotation.*;

/**
 * @author tangsen
 * @date 2023/4/21 13:54
 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Sum {
}

计算的工具类方法

package com.example.demo.util;

import cn.hutool.core.util.NumberUtil;
import com.example.demo.annotation.Sum;
import com.example.demo.entity.DemoDto;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author tangsen
 * @date 2023/4/21 11:27
 **/
public class PolymerizationUtil{

    @SneakyThrows
    public static <T> T sum(List<T> list,Class<T> clazz){
        T firstObject = list.get(0);
        T result = clazz.newInstance();
        Field[] fields = firstObject.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Sum.class)) {
                field.setAccessible(true);
                Object fieldValue = list.stream()
                        .map(obj -> {
                            try {
                                return field.get(obj);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                            return null;
                        })
                        .filter(Objects::nonNull)
                        .reduce((Object a, Object b) -> {
                            if (a instanceof Integer) {
                                return (Integer) a + (Integer) b;
                            } else if (a instanceof BigDecimal) {
                                return (NumberUtil.add((BigDecimal) a,(BigDecimal) b));
                            }else if (a instanceof String) {
                                return (NumberUtil.add(new BigDecimal(a.toString()),new BigDecimal(b.toString()))).toString();
                            } else {
                                return 0;
                            }
                        }).get();
                field.set(result, fieldValue);
            }
        }
        return result;
    }
}

运行结果 注意实体类上需要计算的字段加注解

     public static void main(String[] args) {
          List<Compute> computeList = getList();
          Compute compute = PolymerizationUtil.sum(computeList, Compute.class);
          System.out.println(compute);
     }

这里只做了合计的处理,需要拓展,可以在注解里面加属性,来定义是加减乘除

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值