Ich habe eine List<SomeBean>
, die von einem Webdienst ausgefüllt wird. Ich möchte den Inhalt dieser Liste in eine leere Liste des gleichen Typs kopieren / klonen. Eine Google-Suche zum Kopieren einer Liste schlug mir vor, die Collections.copy()
Methode zu verwenden . In allen Beispielen, die ich gesehen habe, sollte die Zielliste die genaue Anzahl der Elemente enthalten, für die das Kopieren stattfinden soll.
Da die von mir verwendete Liste über einen Webdienst ausgefüllt ist und Hunderte von Objekten enthält, kann ich die oben beschriebene Technik nicht verwenden. Oder ich benutze es falsch ?? !! Wie auch immer, damit es funktioniert, habe ich versucht, so etwas zu tun, aber ich habe immer noch eine IndexOutOfBoundsException
.
List<SomeBean> wsList = app.allInOne(template);
List<SomeBean> wsListCopy=new ArrayList<SomeBean>(wsList.size());
Collections.copy(wsListCopy,wsList);
System.out.println(wsListCopy.size());
Ich habe versucht, das zu verwenden, wsListCopy=wsList.subList(0, wsList.size())
aber ich habe ConcurrentAccessException
später im Code eine. Hit und Versuch. :) :)
Wie auch immer, meine Frage ist einfach: Wie kann ich den gesamten Inhalt meiner Liste in eine andere Liste kopieren? Natürlich nicht durch Iteration.
quelle
app.allInOne(template)
?ArrayList
?Antworten:
Verwenden Sie einfach dies:
Hinweis: Wenn Sie
otherList
von einem anderen Thread aus ändern, ist dies immer noch nicht threadsicher. Möglicherweise möchten Sie diesotherList
(und sogarnewList
)CopyOnWriteArrayList
zum Beispiel festlegen - oder ein Sperrprimitiv wie ReentrantReadWriteLock verwenden, um den Lese- / Schreibzugriff auf beliebige Listen zu serialisieren gleichzeitig zugegriffen.quelle
ConcurrentAccessException
.Dies ist eine wirklich schöne Java 8-Methode:
Der Vorteil hierbei ist natürlich, dass Sie nur einen Teil der Liste filtern und überspringen können.
z.B
quelle
list
wird geändert, während der Kollektor läuft,ConcurrentModificationException
wird a geworfen..limit(list1.size() - 1)
Beachten Sie bitte, dass bei Verwendung der addAll () -Methode zum Kopieren der Inhalt der beiden Array-Listen (originalArrayList und copyArrayofList), die auf dieselben Objekte verweisen, zur Liste hinzugefügt wird. Wenn Sie also eines dieser Objekte ändern, wird auch copyArrayofList geändert spiegeln die gleiche Veränderung wider.
Wenn Sie keinen Nebeneffekt wünschen, müssen Sie jedes Element aus der ursprünglichenArrayList in die copyArrayofList kopieren, z. B. mithilfe einer for- oder while-Schleife.
quelle
Dies bedeutet, dass Sie die Liste ändern, während Sie versuchen, sie zu kopieren, höchstwahrscheinlich in einem anderen Thread. Um dies zu beheben, müssen Sie entweder
Verwenden Sie eine Sammlung, die für den gleichzeitigen Zugriff ausgelegt ist.
Sperren Sie die Sammlung entsprechend, damit Sie sie durchlaufen können (oder Sie können eine Methode aufrufen, die dies für Sie erledigt).
Suchen Sie eine Abwesenheit, um zu vermeiden, dass Sie die ursprüngliche Liste kopieren müssen.
quelle
Ab Java 10 :
List.copyOf()
Gibt eine nicht veränderbare Datei zurück,List
die die Elemente der angegebenen enthältCollection
.Das Gegebene
Collection
darf nicht seinnull
und darf keinenull
Elemente enthalten .Auch, wenn Sie eine tiefe Kopie eines erstellen möchten
List
, können Sie viele gute Antworten finden hier .quelle
Es gibt eine andere Methode mit Java 8 auf null-sichere Weise.
Wenn Sie ein Element überspringen möchten.
quelle
Ich hatte das gleiche Problem ConcurrentAccessException und mysolution war:
Es funktioniert also immer nur eine Operation und vermeidet die Ausnahme ...
quelle
Ich habe etwas Ähnliches versucht und konnte das Problem reproduzieren (IndexOutOfBoundsException). Unten sind meine Ergebnisse:
1) Die Implementierung der Collections.copy (destList, sourceList) überprüft zunächst die Größe der Zielliste durch Aufrufen der size () -Methode. Da der Aufruf der size () -Methode immer die Anzahl der Elemente in der Liste zurückgibt (in diesem Fall 0), stellt der Konstruktor ArrayList (Kapazität) nur die Anfangskapazität des Hintergrundarrays sicher, und dies hat keine Beziehung zu Größe der Liste. Daher erhalten wir immer IndexOutOfBoundsException.
2) Eine relativ einfache Möglichkeit besteht darin, den Konstruktor zu verwenden, der eine Sammlung als Argument verwendet:
quelle
re :
indexOutOfBoundsException
, Ihre Unterlistenargumente sind das Problem; Sie müssen die Unterliste bei Größe 1 beenden. Da das letzte Element einer Liste auf Null basiert, ist es immer Größe 1, es befindet sich kein Element an der Größenposition, daher der Fehler.quelle
Sie können addAll () verwenden.
z.B :
wsListCopy.addAll(wsList);
quelle
Ich kann keine richtige Antwort sehen. Wenn Sie eine tiefe Kopie wünschen, müssen Sie das Objekt manuell iterieren und kopieren (Sie können einen Kopierkonstruktor verwenden).
quelle
Wenn Sie nicht möchten, dass Änderungen in einer Liste eine andere Liste bewirken, versuchen Sie dies. Es hat bei mir funktioniert. Ich
hoffe, das hilft.
quelle
Die Funktion subList ist ein Trick. Das zurückgegebene Objekt befindet sich noch in der ursprünglichen Liste. Wenn Sie also eine Operation in der Unterliste ausführen, wird die gleichzeitige Ausnahme in Ihrem Code verursacht, unabhängig davon, ob es sich um einen einzelnen Thread oder einen Multi-Thread handelt.
quelle