Reputation: 81
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
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
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