java 如何从HashMap〈String,Double>集合中计算平均值

ddarikpa  于 2023-02-02  发布在  Java
关注(0)|答案(2)|浏览(208)

我有一个HashMap〈String,Duble〉的集合,我从multimap中获取。我想计算Map值的平均值,并计算哪个Map键具有最小平均值。数据如下所示:

HashMap<A1, 2.0>
HashMap<A2, 1.0>
HashMap<A1, 3.0>
HashMap<A2, 1.0>

我不明白,谁能给予我点提示?
添加一些更多的数据,说明我为什么使用MultiMap。

{‘Gateway’:’ G1’, ‘Device’: ‘D1’,’position’:{‘rssi’: 1}},
{‘Gateway’:’ G2’, ‘Device’: ‘D1’,’position’:{‘rssi’: 3}},
{‘Gateway’:’ G1’, ‘Device’: ‘D1’,’position’:{‘rssi’: 2}},
{‘Gateway’:’ G2’, ‘Device’: ‘D1’,’position’:{‘rssi’: 5}},
{‘Gateway’:’ G1’, ‘Device’: ‘D1’,’position’:{‘rssi’: 4}},
{‘Gateway’:’ G2’, ‘Device’: ‘D1’,’position’:{‘rssi’: 6}},
..
{‘Gateway’:’ G1’, ‘Device’: ‘D2’,’position’:{‘rssi’: 3}},
{‘Gateway’:’ G2’, ‘Device’: ‘D2’,’position’:{‘rssi’: 2}},

实际上,这是一系列数据到达我的端点,我需要计算哪个设备在哪个网关停留的时间更长。首先,我需要将设备添加到MultiMap中,然后将带有位置的网关添加到Map中。最后,我需要计算平均值,如下所示:

D1-> G1: {1,2,4} => 7/3 = 2.3 
D1-> G2: {3,5,6} => 14/3 = 4.6
5vf7fwbs

5vf7fwbs1#

假设您的Map集合类似于以下内容:

List<Map<String, Double>> mapList = List.of(
        Map.of("A1", 2.0),
        Map.of("A2", 1.0),
        Map.of("A1", 3.0),
        Map.of("A2", 1.0));

你可以直接遍历列表(集合),遍历每个Map平面Map的条目,生成条目流,按键和平均值分组,然后遍历生成的Map,使用比较器按值查找最小值:

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

....


Entry<String, Double> entryWithMinAvg =
        mapList.stream()
               .flatMap(m -> m.entrySet().stream())
               .collect(Collectors.groupingBy(Entry::getKey, Collectors.averagingDouble(Entry::getValue)))
               .entrySet()
               .stream()
               .min(Entry.comparingByValue())
               .get();

System.out.println(entryWithMinAvg);
snvhrwxg

snvhrwxg2#

使用标准Java集合的最简单的多Map实现是Map<K,List<V>>--即从每个键到该键的值列表的Map。

Map<String,List<Double>> multimap;
multimap.computeIfAbsent(key, k -> new ArrayList<>()).add(value);

使用比较器来比较平均值,找到具有最小平均值的键也是微不足道的:

Comparator<String> compareAverageKeys = Comparator.comparingDouble(
    k -> multimap.get(k).stream().mapToDouble(v -> v).average().get());
multimap.keys().stream().min(compareAverageKeys);

如果创建集合的唯一目的是找到平均值,那么您可以只保留统计数据而不是键:

Map<String,DoubleSummaryStatistics> stats;

stats.computeIfAbsent(key, k -> new DoubleSummaryStatistics()).add(value);

那么找到具有最小值的密钥要简单得多并且更有效:

stats.keys().stream().min(Comparator.comparingDouble(k -> stats.get(k).getAverage());

相关问题