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);