BMonty
BMonty

Reputation: 43

Each object stored in Map returns values stored in last object

I checked for a few solutions on this but they all seem to say the issue is when people use the "static" word or aren't using the class name when creating the HashMap. I am trying to create a map that contains a person's name (key) and their test scores (value). I am trying to pass an object in for the value do this:

HashMap<String, Scores> map = new HashMap<String, Scores>();

List<Integer> scores = new ArrayList<Integer>();
scores.add(55);
scores.add(66);
scores.add(77);

map.put("foo", new Scores(scores));

scores.clear();

scores.add(70);
scores.add(80);
scores.add(90);

map.put("bar", new Scores(scores));

System.out.println(map.get("foo").getScores());
System.out.println(map.get("bar").getScores());
System.out.println(map.get("foo").getAverage());

and for my Scores Class I have the following:

List<Integer> scores = new ArrayList<Integer>();
private int sum = 0;

public Scores(List<Integer> s){
    this.scores = s;
}

public double getAverage(){
    int count = 0;
    for (int x: this.scores){
        this.sum += x;
        count++;
    }
    return this.sum / count;
}

public List<Integer> getScores(){
    return this.scores;
}

When I run my code I get the following output:

[70, 80, 90]
[70, 80, 90]
80.0

I am not using "static" to store my scores and I use clear() afterwards to keep old values from repeating. I am also using the class name when creating my HashMap<> variable.

Can anyone tell me why both 'map.get("foo")' and 'map.get("bar")' return the same values and how I might fix this? Can they also provide a working example? Thanks!

Upvotes: 2

Views: 61

Answers (2)

facundop
facundop

Reputation: 482

Primitives (byte, short, int, long, float, double, boolean, char, etc) and reference types (any instantiable class as well as arrays. String, Scanner, Random, Die, int[], String[] , etc.) have different behaviors.

You will need to actually instantiate a new ArrayList - like this:

scores = new ArrayList<Integer>();

to create a new list. In your code, you are just passing a reference to the same list.

Upvotes: 0

Eran
Eran

Reputation: 393801

new Scores(scores) doesn't create a copy of the List instance passed to it. It stores a reference to that List.

Therefore both Scores instances you put as values in the Map refer to the same List.

Instead of

scores.clear();

you should create a new List :

scores = new ArrayList<Integer>();

in order for the two Scores instances to refer to different Lists.

Upvotes: 3

Related Questions