Warum funktioniert meine ArrayList enthalten, die N Kopien des letzten Elements der Liste Hinzugefügt?
Ich bin Sie drei verschiedene Objekte zu einer ArrayList, aber die Liste enthält drei Kopien des letzten Objekts fügte ich hinzu.
Beispiel:
for (Foo f : list) {
System.out.println(f.getValue());
}
Erwartet:
0
1
2
Aktuell:
2
2
2
Welche Fehler habe ich gemacht?
Anmerkung: dieses ist entworfen, um eine kanonische Q&A für eine Vielzahl ähnlicher Probleme, die entstehen, die auf dieser Website.
InformationsquelleAutor Duncan Jones | 2013-11-07
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dieses problem hat zwei typische Ursachen:
Statische Felder verwendet, indem die Objekte, die Sie gespeichert in der Liste
Versehentlich hinzufügen der gleichen Objekt auf der Liste
Statische Felder
Wenn die Objekte in der Liste speichern von Daten in statische Felder, jedes Objekt in Ihrer Liste angezeigt wird, zu sein die selben, weil Sie die gleichen Werte. Betrachten Sie die folgende Klasse:
In diesem Beispiel gibt es nur eine
int value
die gemeinsam zwischen allen Instanzen desFoo
weil es deklariert iststatic
. (Siehe die "Verständnis-Klasse-Mitglieder" tutorial.)Wenn Sie hinzufügen, mehrere
Foo
Objekte, um eine Liste mit dem code unten, wird jede Instanz zurück3
von einem AufrufgetValue()
:Die Lösung ist einfach - verwenden Sie nicht den
static
keywords für Felder in Ihrer Klasse, wenn Sie tatsächlich wollen, dass die gemeinsamen Werte zwischen jeder Instanz der Klasse.Hinzufügen das Gleiche Objekt
Wenn Sie fügen Sie eine temporäre variable zu einer Liste, erstellen Sie eine neue Instanz des Objekts, die Sie hinzufügen, jedes mal, wenn Sie loop. Betrachten Sie die folgenden fehlerhaften code-snippet:
Hier, die
tmp
Objekt gebaut wurde, außerhalb der Schleife. Als Ergebnis, die gleiche Objekt-Instanz wird Hinzugefügt, um die Liste drei mal. Die Instanz den Wert2
, denn das war der Wert übergeben, während der Letzte AufrufsetValue()
.Um dies zu beheben, bewegen Sie einfach die Objekt-Konstruktion im inneren der Schleife:
Da das gleiche Objekt (
tmp
) wird Hinzugefügt, um die Liste drei mal. Und dieses Objekt hat den Wert zwei, da der Aufruftmp.setValue(2)
in der letzten iteration der Schleife.ok also hier problem ist, weil der gleiche Gegenstand ist , Ist es so, wenn ich hinzufügen, Gleiches Objekt drei mal in einer array-Liste ,alle drei Standort von arraylist obj beziehen sich auf dasselbe Objekt?
Yup, genau das ist es.
Eine Tatsache, die ich zunächst übersehen: im Hinblick auf den Teil
you must create a new instance each time you loop
im AbschnittAdding the same object
: Bitte beachten Sie die Instanz bezeichnet, betrifft das Objekt, das Sie hinzufügen, NICHT das Objekt, das Sie hinzufügen.InformationsquelleAutor
Dein problem ist mit der Art
static
erfordert eine neue Initialisierung jedes mal, wenn eine Schleife iteriert wird. Wenn Sie in einer Schleife ist, ist es besser, um die konkrete Initialisierung in der Schleife.Statt:
Hier
tag
ist eine variable inSomeStaticClass
zu überprüfen, die Gültigkeit der oben genannten snippet; Sie können einige andere Implementierung, basierend auf Ihren Anwendungsfall.static
"? Was wäre eine nicht-statische Klasse für Sie?z.B. nicht-statische:
public class SomeClass{/*some code*/}
& statisch:public static class SomeStaticClass{/*some code*/}
. Ich hoffe es ist klarer jetzt.Da alle Objekte einer statischen Klasse haben die gleiche Adresse, wenn Sie initialisiert sind in einer Schleife und werden mit unterschiedlichen Werten in jeder iteration. Alle von Ihnen hätten einen identischen Wert, die gleich dem Wert der letzten iteration, oder wenn das Letzte Objekt geändert wurde. Ich hoffe es ist klarer jetzt.
InformationsquelleAutor Shashank
Hatte das gleiche Problem mit dem calendar-Instanz.
Falscher code:
Haben Sie ein NEUES Objekt erstellen des Kalenders, was kann getan werden, mit
calendar.clone()
;InformationsquelleAutor basti12354
Jedes mal, wenn Sie ein Objekt hinzufügen, eine ArrayList, machen Sie sicher, fügen Sie ein neues Objekt ist und nicht bereits verwendet Objekt. Was geschieht, ist, dass, wenn Sie fügen Sie die gleichen 1-Kopie des Objekts, das gleiche Objekt wird Hinzugefügt, um die verschiedenen Positionen in einer ArrayList. Und wenn Sie sich ändern, weil die gleiche Kopie Hinzugefügt wird, immer und immer wieder, alle Exemplare betroffen zu bekommen.
Zum Beispiel,
Angenommen, Sie haben eine ArrayList wie diese:
Fügen Sie nun diese Karte c auf der Liste, es wird Hinzugefügt werden, kein problem. Es wird gespeichert an Position 0. Aber wenn Sie speichern die gleiche Karte c in der Liste gespeichert wird auf Position 1. Also denken Sie daran, dass Sie Hinzugefügt haben, gleichen 1-Objekt an zwei verschiedenen Standorten in einer Liste. Nun, wenn Sie eine änderung vornehmen, Karte, Objekt c, die Objekte in einer Liste an Position 0 und 1 werden auch darüber nachdenken, dass zu ändern, weil Sie das gleiche Objekt.
Eine Lösung wäre ein Konstruktor in-Karte-Klasse, nimmt eine andere Karte Objekt. Dann wird in diesen Konstruktor können Sie die Eigenschaften wie dieses:
Und können sagen, Sie haben die gleichen 1-Kopie der Karte, so an der Zeit, das hinzufügen eines neuen Objekts, können Sie dies tun:
InformationsquelleAutor Faraz Durrani