优化java加权方法

1. 场景

需要对不同类型对象、不同类型的字段,求加权值;

2. 抽象字段

使用 Function 抽象字段,后面处理 字段类型;

java 复制代码
	private BigDecimal getWeightValueByListAndFunc(List<ZjCentralEnterprise> filterList, Function<ZjCentralEnterprise, BigDecimal> heatValueGet
            , Function<ZjCentralEnterprise, BigDecimal> qtyGetFunc, int scale) {
        Map<String, BigDecimal> heatValueMap = new HashMap<>();
        Map<String, BigDecimal> quantityMap = new HashMap<>();
        List<String> keys = new ArrayList<>();
        for (int i = 0; i < filterList.size(); i++) {
            String key = String.valueOf(i);
            keys.add(key);
            heatValueMap.put(key, heatValueGet.apply(filterList.get(i)));
            quantityMap.put(key, qtyGetFunc.apply(filterList.get(i)));
        }
        BigDecimal weight = NumberUtils.calculateAverageWeight2(heatValueMap, quantityMap, scale);
        return weight;
    }

2. 抽象对象

使用 T 抽象对象

java 复制代码
    public static <T> BigDecimal weightedAverage(List<T> list,
                                                 Function<T, BigDecimal> valueFunc,
                                                 Function<T, BigDecimal> weightFunc,
                                                 int scale) {
        if (list == null || list.isEmpty()) {
            return BigDecimal.ZERO;
        }

        Map<String, BigDecimal> valueMap = new HashMap<>();
        Map<String, BigDecimal> weightMap = new HashMap<>();

        for (int i = 0; i < list.size(); i++) {
            String key = String.valueOf(i);
            T item = list.get(i);
            valueMap.put(key, valueFunc.apply(item));
            weightMap.put(key, weightFunc.apply(item));
        }

        return NumberUtils.calculateAverageWeight2(valueMap, weightMap, scale);
    }

    public static <T> Integer weightedAverage2(List<T> list,
                                               Function<T, Integer> valueFunc,
                                               Function<T, BigDecimal> weightFunc) {
        if (list == null || list.isEmpty()) {
            return 0;
        }

        Map<String, BigDecimal> valueMap = new HashMap<>();
        Map<String, BigDecimal> weightMap = new HashMap<>();

        for (int i = 0; i < list.size(); i++) {
            String key = String.valueOf(i);
            T item = list.get(i);
            valueMap.put(key, new BigDecimal(String.valueOf(valueFunc.apply(item))));
            weightMap.put(key, weightFunc.apply(item));
        }

        BigDecimal bg = NumberUtils.calculateAverageWeight2(valueMap, weightMap, 0);
        return bg.intValue();
    }

3. 抽象字段类型

使用 v 抽象字段类型

bash 复制代码
public static <T, V extends Number> BigDecimal calcWeightedAverage(
            List<T> list,
            Function<T, V> valueFunc,
            Function<T, BigDecimal> weightFunc,
            int scale
    ) {
        if (list == null || list.isEmpty()) {
            return BigDecimal.ZERO;
        }

        Map<String, BigDecimal> valueMap = new HashMap<>();
        Map<String, BigDecimal> weightMap = new HashMap<>();

        for (int i = 0; i < list.size(); i++) {
            String key = String.valueOf(i);
            T item = list.get(i);

            // 核心:自动将任意 Number 转为 BigDecimal(兼容 Integer/Long/Double)
            V value = valueFunc.apply(item);
            BigDecimal valueBig = new BigDecimal(value.toString());

            BigDecimal weight = weightFunc.apply(item);

            valueMap.put(key, valueBig);
            weightMap.put(key, weight);
        }

        // 调用你原有加权计算方法
        return NumberUtils.calculateAverageWeight2(valueMap, weightMap, scale);
    }

4. 公共方法

java 复制代码
public static BigDecimal calculateAverageWeight2(
            Map<String, BigDecimal> cumPurchaseHeatValueMap,
            Map<String, BigDecimal> cumPurchaseMap, int scale) {

        if (cumPurchaseHeatValueMap == null || cumPurchaseMap == null) {
            return null;
        }
        List<String> keyList = new ArrayList<>(cumPurchaseHeatValueMap.keySet());
        BigDecimal sumProduct = BigDecimal.ZERO;  // 分子:热值与采购数量的乘积之和
        BigDecimal sumQuantity = BigDecimal.ZERO; // 分母:采购数量之和

        for (String key : keyList) {
            BigDecimal heatValue = cumPurchaseHeatValueMap.get(key);
            BigDecimal purchaseQuantity = cumPurchaseMap.get(key);

            // 如果任一值为null,跳过该物料
            if (heatValue != null && purchaseQuantity != null && heatValue.doubleValue() > 0 && purchaseQuantity.doubleValue() > 0) {
                sumProduct = sumProduct.add(heatValue.multiply(purchaseQuantity));
                sumQuantity = sumQuantity.add(purchaseQuantity);
            }
        }

        // 如果分母为0,返回null
        if (sumQuantity.compareTo(BigDecimal.ZERO) == 0) {
            return null;
        }

        return sumProduct.divide(sumQuantity, scale, RoundingMode.HALF_UP);
    }

5. 使用

第二个参数类型 和返回值类型 相同

java 复制代码
        Integer heatValue2 = NumberUtils.calcWeightedAverage(list, ZjPowerPlantCoalData::getCalorificValue, ZjPowerPlantCoalData::getQuantity, 0).intValue();
        Long heatValue3 = NumberUtils.calcWeightedAverage(list, ZjPowerPlantCoalData::getCalorificValue, ZjPowerPlantCoalData::getQuantity, 0).longValue();
        Double closingPrice = NumberUtils.calcWeightedAverage(list, ZjPowerPlantCoalData::getClosingPrice, ZjPowerPlantCoalData::getQuantity, 2).doubleValue();
        BigDecimal closingPrice2 = NumberUtils.calcWeightedAverage(list, ZjPowerPlantCoalData::getClosingPrice, ZjPowerPlantCoalData::getQuantity, 2);
相关推荐
咩咩啃树皮7 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚7 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白9 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司9 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地10 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun31415910 小时前
TCP超时重传机制是为了解决什么问题?
java
莫逸风13 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
z1234567898613 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin52112314 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python
做个文艺程序员14 小时前
Linux第24篇:Java应用监控体系搭建:Prometheus+Grafana可视化运维
java·grafana·prometheus