Каждый объект, сохраненный на карте, возвращает значения, сохраненные в последнем объекте

#java #arraylist #hashmap

#java #arraylist #hashmap

Вопрос:

Я проверил несколько решений по этому вопросу, но все они, похоже, говорят, что проблема заключается в том, что люди используют «статическое» слово или не используют имя класса при создании HashMap. Я пытаюсь создать карту, содержащую имя человека (ключ) и его результаты тестов (значение). Я пытаюсь передать объект для значения, сделайте это:

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

и для моего класса Scores у меня есть следующее:

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

Когда я запускаю свой код, я получаю следующий вывод:

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

Я не использую «static» для хранения своих результатов, и я использую clear () впоследствии, чтобы старые значения не повторялись. Я также использую имя класса при создании моей переменной HashMap<>.

Кто-нибудь может сказать мне, почему оба ‘map.get («foo»)’ и ‘map.get («bar»)’ возвращают одни и те же значения и как я мог бы это исправить? Могут ли они также предоставить рабочий пример? Спасибо!

Комментарии:

1. вы назначаете один и тот же объект списка всем ключам вашей карты. Это как если бы вы помещали разные стикеры на одну и ту же коробку для торта…

Ответ №1:

new Scores(scores) не создает копию List экземпляра, переданного ему. Он хранит ссылку на это List .

Поэтому оба Scores экземпляра, которые вы помещаете в качестве значений в Map , относятся к одному и тому же List .

Вместо

 scores.clear();
  

вы должны создать новый List :

 scores = new ArrayList<Integer>();
  

для того, чтобы два Scores экземпляра ссылались на разные List s.

Ответ №2:

Примитивы (byte, short, int, long, float, double, boolean, char и т.д.) И ссылочные типы (любой создаваемый класс, а также массивы. String, Scanner, Random, Die, int[], String[] и т.д.) Имеют разное поведение.

Вам нужно будет фактически создать экземпляр нового ArrayList — вот так:

scores = new ArrayList<Integer>();

для создания нового списка. В вашем коде вы просто передаете ссылку на тот же список.