У этой проблемы есть две типичные причины:
Статические поля, используемые объектами, которые вы сохранили в списке
Случайное добавление того же объекта в список
Статические поля
Если объекты в вашем списке хранят данные в статических полях, каждый объект в вашем списке будет выглядеть одинаково, потому что они содержат одинаковые значения. Рассмотрим класс ниже:
public class Foo {
private static int value;
public Foo(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
В этом примере есть только один, int value
который используется всеми экземплярами, Foo
потому что он объявлен static
. (См. Учебник «Общие сведения о членах класса» .)
Если вы добавите несколько Foo
объектов в список, используя приведенный ниже код, каждый экземпляр вернется 3
после вызова к getValue()
:
for (int i = 0; i < 4; i++) {
list.add(new Foo(i));
}
Решение простое - не используйте static
ключевые слова для полей в вашем классе, если вы действительно не хотите, чтобы значения разделялись между каждым экземпляром этого класса.
Добавление того же объекта
Если вы добавляете временную переменную в список, вы должны создавать новый экземпляр объекта, который вы добавляете, каждый раз при выполнении цикла. Рассмотрим следующий фрагмент ошибочного кода:
List<Foo> list = new ArrayList<Foo>();
Foo tmp = new Foo();
for (int i = 0; i < 3; i++) {
tmp.setValue(i);
list.add(tmp);
}
Здесь tmp
объект был построен вне цикла. В результате один и тот же экземпляр объекта добавляется в список трижды. Экземпляр будет содержать значение 2
, потому что это значение было передано во время последнего вызова setValue()
.
Чтобы исправить это, просто переместите конструкцию объекта внутрь цикла:
List<Foo> list = new ArrayList<Foo>();
for (int i = 0; i < 3; i++) {
Foo tmp = new Foo();
tmp.setValue(i);
list.add(tmp);
}