优化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);
相关推荐
AskHarries37 分钟前
系统提示词、开发者指令和用户输入的优先级
java·前端·数据库
daidaidaiyu1 小时前
ThingsBoard 规则链系统源码分析和自定义定时器
java
小毛驴8502 小时前
spring-boot-maven-plugin,maven-compiler-plugin 功能对比
java·python·maven
csdn_aspnet2 小时前
Java 霍尔分区算法(Hoare‘s Partition Algorithm)
java·开发语言·算法
霸道流氓气质2 小时前
通义灵码 IDEA 插件完全使用指南
java·ide·intellij-idea
诸葛务农2 小时前
道路行驶条件下电动汽车永磁电机的有效使用寿命及永磁体的失效和回收再利用(下)
java·开发语言·算法
Percep_gan2 小时前
Java8中的stream的测试使用
java
砍材农夫3 小时前
物联网实战:Spring Boot MQTT | MQTT 设备模拟器演示(附源码)
java·spring boot·后端·物联网·spring·netty
EAIReport3 小时前
Spring AI 详解:Java 开发者快速落地 AI 应用
java·人工智能·spring
YDS8293 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— Agent执行链路设计之ReAct Loop
java·spring boot·ai·agent·deepseek