zkranc
zkranc

Reputation: 81

java update hashmap

I have a problem with changing values in an HashMap>. First I do this:

HashMap<String, ArrayList<Integer>> countries = new HashMap<>();
ArrayList<Integer> medals = new ArrayList<>();
medals.add(0); medals.add(0); medals.add(0);
for(int i = 0; i < COUNTRY.length; i++){
    countries.put(COUNTRY[i], medals);
}

I fill the HashMap with keys from a static array and add a default value of an ArrayList that is filled with 0, 0, 0. Then I do this:

Integer plus = new Integer(1);
for(int j = 0; j < athletes.size(); j++){
    if(j == 3)
        break;
    Athlete a = athletes.get(j);
    ArrayList<Integer> medals = countries.get(a.getCountry());
    Integer medal = medals.get(j) + plus;
    medals.set(j, medal);
    countries.put(a.getCountry(), medals);
}

I have an ArrayList filled with athletes that is already sorted by the athlete's results. What I'm trying to do is take the top 3 placed athletes, and update my HashMap value so the ArrayList will have 3 numbers that represent how many gold, silver and bronze medals every country has won. The problem is that when I try to replace the old value with a new ArrayList it replaces all the values in the HashMap with new ArrayList's instead of just the one with the matching key.

I have no idea what the problem is, any suggestions??

Upvotes: 1

Views: 441

Answers (2)

jlordo
jlordo

Reputation: 37813

The problem is in this piece of code:

HashMap<String, ArrayList<Integer>> countries = new HashMap<>();
ArrayList<Integer> medals = new ArrayList<>();
medals.add(0); medals.add(0); medals.add(0);
for(int i = 0; i < COUNTRY.length; i++){
    countries.put(COUNTRY[i], medals);
}

You only create a single instance of your List, and associate it with every country.

A possible fix would be to initialize a new List in each loop iteration.

HashMap<String, List<Integer>> countries = new HashMap<>();
for(int i = 0; i < COUNTRY.length; i++){
    List<Integer> medals = Arrays.asList(0, 0, 0);
    countries.put(COUNTRY[i], medals);
}

If your List has the fixed size of 3, why don't you use a simple int[] instead?

This is how the code would look using an int[]

Map<String, int[]> countries = new HashMap<>();
for(int i = 0; i < COUNTRY.length; i++){
    countries.put(COUNTRY[i], new int[3]);
}
//
for(int j = 0; j < athletes.size(); j++){
    if(j == 3)
        break;
    Athlete a = athletes.get(j);
    int[] medals = countries.get(a.getCountry());
    medals[j]++;
    // last to lines could even be
    // countries.get(a.getCountry())[j]++;
}

Upvotes: 8

Priyank Doshi
Priyank Doshi

Reputation: 13151

You should use google-guava's MultiMap . It is design for exactly this situation where you need Map<K,List<V>> type of structure. i.e. multiple value for same key.

Upvotes: 0

Related Questions