如何计算具有相同键的hashmap值的平均值

时间:2016-04-11 18:19:19

标签: java hashmap

所以我有这个程序,用相同的键但不同的值来计算所有petshops的总和。但是,现在,我想用相同的密钥计算每个宠物店的平均值。我正在考虑使用计数器来获得arraylist中包含多少次petshop。但它不起作用。我需要为每个循环运行另一个吗?

public class AverageCost {

    public void calc(ArrayList<Pet> pets) { 

        Map<String, Double> hm = new HashMap<>();

        for (Pet i : pets) {
            String name = i.getShop();
            // If the map already has the pet use the current value, otherwise 0.
            double price = hm.containsKey(name) ? hm.get(name) : 0;
            price += i.getPrice();
            hm.put(name, price);

        }
        System.out.println("");
        for (String key : hm.keySet()) {
            System.out.printf("%s: %s%n", key, hm.get(key));
        }

    }

3 个答案:

答案 0 :(得分:1)

您可以在地图中引入第二张地图进行计数或使用复合值对象来保存累积价格和宠物数量:

Map<String, PetStatistics> hm = new HashMap<>();
for (Pet i : pets) {
    String name = i.getShop();
    // If the map already has the pet use the current value, otherwise 0.

    PetStatistics stats = hm.get(name);
    if (stats == null) {
        stats = new PetStatistics(0, 0); // count and price
        hm.put(name, stats);
    }
    stats.addPrice(i.getPrice());
    stats.incrementCount();
}

答案 1 :(得分:1)

您要求的是一种计算累积移动平均线的算法,而不存储您目前累积的术语数。我不认为这是可能的(例如,请参阅https://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average其中&#39; n&#39;,到目前为止,这些术语的数量是必需的)。我的建议是使用两个通道 - 第一个存储数字,第二个计算平均数。

public void calc(List<Pet> pets) {
    // First pass
    Map<String, List<Double>> firstPass = new HashMap<>();
    for (Pet pet : pets) {
        String name = pet.getShop();
        if (firstPass.containsKey(name)) {
            firstPass.get(name).add(pet.getPrice());
        } else {
            List<Double> prices = new ArrayList<>();
            prices.add(pet.getPrice());
            firstPass.put(name, prices);
        }
    }

    // Second pass
    Map<String, Double> results = new HashMap<>();
    for (Map.Entry<String, List<Double>> entry : firstPass.entrySet()) {
        Double average = calcAverage(entry.getValue());
        results.put(entry.getKey(), average);
        // Print results
        System.out.printf("%s: %s%n", entry.getKey(), average);
    }
}

private double calcAverage(List<Double> values) {
    double result = 0;
    for (Double value : values) {
        result += value;
    }
    return result / values.size();
}

答案 2 :(得分:1)

您可以使用Collections.frequency获取出现次数并除以总和

for (String key : hm.keySet()) {
    int w = Collections.frequency(pets, new Pet(key));
    System.out.printf("%s: %s%n", key, hm.get(key)/w);
}