2

So I am having a problem where I have to add up all values with the same key in my HashMap. The data(petshop and pet price) is retrieve from an ArrayList. at the moment, the program only gets the last value for each shop since there are multiple shops with the same name but different pet price. I would like to be able to sum the pet price for each shop. so if we have for example,
Law Pet shop: 7.00
and another Law Pet shop: 5.00,
I would like to output it like this:
Law Pet shop: 13.00.
Here is the code and output:

public class AverageCost {

    public void calc(ArrayList<Pet> pets){

        String name = "";
        double price = 0;
        HashMap hm = new HashMap();

        for (Pet i : pets) {
            name = i.getShop();
            price = i.getPrice();

            hm.put(name, price);
        }

        System.out.println("");
        // Get a set of the entries
        Set set = hm.entrySet();
        // Get an iterator
        Iterator i = set.iterator();
        // Display elements
        while(i.hasNext()) {

            Map.Entry me = (Map.Entry)i.next();
            System.out.print(me.getKey() + ": ");
            System.out.println(me.getValue());
        }
    }
}

At the moment this is the output:

Aquatic Acrobatics: 7.06
The Briar Patch Pet Store: 5.24
Preston Pets: 18.11
The Menagerie: 18.7
Galley Pets: 16.8
Anything Except Badgers: 8.53
Petsmart: 21.87
Morris Pets and Supplies: 7.12

6
  • Which version of Java do you use (6, 7 or 8)? What is the expected result? Commented Apr 11, 2016 at 16:36
  • 6
    Did you know that a HashMap can NOT have duplicate keys? there will only be one value associated to the same key, so your question doesn't make much sense. Commented Apr 11, 2016 at 16:36
  • @NicolasFilotto I am using 7 Commented Apr 11, 2016 at 16:39
  • @ÓscarLópez yes i know that they can have only one key but I thought there was a way to add the values of the shops with the same key Commented Apr 11, 2016 at 16:40
  • 3
    Then, check if the key exists in your map before putting. If it exists then add new amount to the current amount. Commented Apr 11, 2016 at 16:41

4 Answers 4

8

First, please program to the interface (not the concrete collection type). Second, please don't use raw types. Next, your Map only needs to contain the name of the pet and the sum of the prices (so String, Double). Something like,

public void calc(List<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: %.2f%n", key, hm.get(key));
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Correct! however, I do not really understand the last for each loop. I don't want to be a pain but could you please break it down?
For each key in the Map (the keySet), print (using formatted output) the key and the value referenced by the key (hm.get(key)).
oh ok, but in this case how do I do if I want to calculate the average of price for each shop? because I wouldn't have the number of each shop...
oh I figured it out, I just have to do for (String key : hm.keySet()) { System.out.printf("%s: %.2f%n", key, hm.get(key)/hm.size()); }
5

In Java 8 you could use streams api to do this:

Map<String, Double> map = 
        pets.stream().collect(
            Collectors.groupingBy(
                Pet::getShop,
                Collectors.summingDouble(Pet::getPrice)
            )
        );

Comments

3

There is a useful method V getOrDefault(Object key, V defaultValue) in the Map interface. It returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key. In our case it could be used like this:

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

        for (Pet i : pets) {
            name = i.getShop();
            price = i.getPrice();

            hm.put(name, getOrDefault(name, 0) + price);
        }

In addition, we could get more elegant solution using method reference in Java 8:

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

        for (Pet i : pets) {
            name = i.getShop();
            price = i.getPrice();

            hm.merge(name, price, Double::sum);
        }

Comments

1

If you the sum then you need add up the value you should be getting the value from HashMap and adding the price to that

double price = hm.get(name) == null ? 0 : hm.get(name) ;
hm.put(name,price + i.getPrice())

;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.