Viv*_*thi 10 java java-8 java-stream
如何计算加权平均值,Map<Double, Integer>其中整数值是要平均的Double值的权重.例如:Map有以下元素:
我希望使用Java 8流应用以下公式,但不确定如何一起计算分子和分母并同时保留它.如何在这里使用减少?
Tun*_*aki 16
您可以为此任务创建自己的收集器:
static <T> Collector<T,?,Double> averagingWeighted(ToDoubleFunction<T> valueFunction, ToIntFunction<T> weightFunction) {
    class Box {
        double num = 0;
        long denom = 0;
    }
    return Collector.of(
             Box::new,
             (b, e) -> { 
                 b.num += valueFunction.applyAsDouble(e) * weightFunction.applyAsInt(e); 
                 b.denom += weightFunction.applyAsInt(e);
             },
             (b1, b2) -> { b1.num += b2.num; b1.denom += b2.denom; return b1; },
             b -> b.num / b.denom
           );
}
此自定义收集器将两个函数作为参数:一个函数返回用于给定流元素的值(作为a ToDoubleFunction),另一个函数返回权重(作为a ToIntFunction).它使用一个辅助本地类,在收集过程中存储分子和分母.每次接受一个条目时,分子会增加,其结果是将该值与其权重相乘,分母随着权重而增加.然后,终结者将两者的分割作为a Double.
示例用法是:
Map<Double,Integer> map = new HashMap<>();
map.put(0.7, 100);
map.put(0.5, 200);
double weightedAverage =
  map.entrySet().stream().collect(averagingWeighted(Map.Entry::getKey, Map.Entry::getValue));
| 归档时间: | 
 | 
| 查看次数: | 5684 次 | 
| 最近记录: |