Ten problem ma dwie typowe przyczyny:
Pola statyczne
Jeśli obiekty na liście przechowują dane w polach statycznych, każdy obiekt na liście będzie wyglądał tak samo, ponieważ mają te same wartości. Rozważ poniższą klasę:
public class Foo {
private static int value;
public Foo(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
W tym przykładzie jest tylko jeden, int value
który jest współużytkowany przez wszystkie wystąpienia, Foo
ponieważ jest zadeklarowany static
. (Zobacz samouczek „Zrozumienie składowych klas” ).
Jeśli dodasz wiele Foo
obiektów do listy za pomocą poniższego kodu, każda instancja zwróci 3
z wywołania getValue()
:
for (int i = 0; i < 4; i++) {
list.add(new Foo(i));
}
Rozwiązanie jest proste - nie używaj static
słów kluczowych dla pól w swojej klasie, chyba że faktycznie chcesz, aby wartości były wspólne dla wszystkich wystąpień tej klasy.
Dodawanie tego samego obiektu
Jeśli dodasz zmienną tymczasową do listy, za każdym razem, gdy wykonujesz pętlę, musisz utworzyć nową instancję dodawanego obiektu. Rozważ następujący błędny fragment kodu:
List<Foo> list = new ArrayList<Foo>();
Foo tmp = new Foo();
for (int i = 0; i < 3; i++) {
tmp.setValue(i);
list.add(tmp);
}
Tutaj tmp
obiekt został skonstruowany poza pętlą. W rezultacie ta sama instancja obiektu jest dodawana do listy trzy razy. Instancja będzie przechowywać wartość 2
, ponieważ była to wartość przekazana podczas ostatniego wywołania funkcji setValue()
.
Aby to naprawić, po prostu przesuń konstrukcję obiektu wewnątrz pętli:
List<Foo> list = new ArrayList<Foo>();
for (int i = 0; i < 3; i++) {
Foo tmp = new Foo();
tmp.setValue(i);
list.add(tmp);
}