2016-04-11 28 views
0

Bu nedenle, tüm petshops'ların toplamını aynı anahtarla ancak farklı değerler ile hesaplayan bu programa sahibim. Ancak, şimdi, her bir petshop'un ortalamasını aynı anahtarla hesaplamak istiyorum. Arraylist'te bir petshop'un kaç kez yer aldığını öğrenmek için bir tezgah kullanmayı düşünüyordum. Ama bu çalışmıyor. Her döngü için başka bir tane çalıştırmam gerekecek mi?aynı anahtarla hashmap değerlerinin ortalamasını hesaplama

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

    } 
+7

bölebilirsiniz. Bir HashMap'de yinelenen anahtarlarınız olamaz. Yani, "her bir petshop'unun ortalamasını aynı anahtarla hesaplamak istiyorum" derken, her tuş için sadece bir giriş olacak. – Austin

+0

Sen sayım için ikinci haritayı tanıtmak veya evcil hayvanların hem birikmiş fiyatı ve numarayı tutmak için haritadaki bileşik değeri nesneyi kullanabilirsiniz: 'Harita Belki hm' – hoaz

+0

Eğer HashMap üzerinde ortalamasını saklamak için çalışıyoruz, yok ? – marcellorvalle

cevap

1

olduğunu birikmiş olan terimleri biriktirmeden birikmiş hareketli ortalama. Bunun mümkün olduğunu düşünmüyorum (örneğin, bkz. https://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average, 'n', şu ana kadar geçen terimlerin sayısı gereklidir). Benim önerim iki geçişi kullanmaktır - ilk sayıları saklamak ve ikincisi ortalamaları hesaplamak için.

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(); 
} 
1

Sen sayımı için ikinci haritayı tanıtmak veya evcil hayvanların hem birikmiş fiyatı ve numarayı tutmak için haritadaki bileşik değeri nesneyi kullanabilirsiniz: Ne soruyorsunuz hesaplamak için bir algoritma

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(); 
} 
+0

'put' içindeki' put() 'i hareket ettirin. – Andreas

+0

oh, güzel yakalama. Teşekkürler – hoaz

+0

Öneri: 'PetStatistics' tezgahın kendisini artırmalı. sınıf tüm bu yöntemleri desteklemesi için basit çağrı 'addPrice()' yeterlidir: 'getTotalPrice()' 'getMaxPrice()' 'getMinPrice()' 'getAveragePrice()' 'getPriceCount()' ve ne olursa olsun Diğer istatistik fiyatları bir dizi gereklidir. – Andreas

1

Sen oluşma numarası almak için Collections.frequency kullanmak ve soruyla ben biraz kafam karıştı bütün toplamı

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