Ich möchte Code wie folgt schreiben -
%Vor% aber ich habe java.util.ConcurrentModificationException
Ich habe versucht, auch Iterator
zu verwenden, aber ich habe das gleiche Exception
Erklärung, warum es ConcurrentModificationException
für jede Schleife erstellt auch intern einen Iterator des entrySet
von map
. Während des Iterierens über die Karte haben Sie die Struktur der Karte geändert, indem Sie den Wert erneut in die Karte ( map.put(x,value)
) gesetzt haben, die dieses ConcurrentModificationException
verursacht.
Es ist sogar in der Dokumentation -
Die Iteratoren, die von der Sammelansicht dieser Klasse zurückgegeben wurden Methoden "sind Fail-Fast: wenn die Karte strukturell an irgendeiner geändert wird Zeit, nachdem der Iterator erstellt wurde, in keiner Weise außer durch iterator eigenen remove-Methode, wird der Iterator werfen ConcurrentModificationException. So angesichts der gleichzeitigen Änderung, der Iterator schlägt schnell und sauber, anstatt riskieren willkürliches, nicht-deterministisches Verhalten zu einer unbestimmten Zeit in der Zukunft.
Wie löst man das -
?Sie müssen die Struktur dieser Map während des Iterierens ändern, Sie können diese Werte später einfügen, wie eine temporäre Map behalten und diese nach Abschluss der Iteration hinzufügen.
%Vor%Iterate über eine Kopie und Sie können einfach hinzufügen / entfernen:
%Vor% Es sind noch nicht einmal mehr Codezeilen, da die Kopie direkt über den Kopierkonstruktor erstellt wird. LinkedHashMap
wurde gewählt, um die Iterationsreihenfolge beizubehalten (falls das wichtig ist).
Sie müssen eine Kopie Ihrer Map mit dem Kopierkonstruktor erstellen. Iteriere jetzt 1 und ändere die zweite Karte. Ich gehe davon aus, dass Sie neu hinzugefügten Wert nicht iterieren müssen, da es nicht viel Sinn macht.
Sie können Ihre Aufgabe erreichen, indem Sie eine Kopie erstellen, weil die Schlüssel in beiden gleich bleiben.
BEARBEITEN:
Ich halte es nicht für eine gute Idee, das neu hinzugefügte Element zu einer Hashmap zu iterieren. Wenn Sie die von Iterator bereitgestellten APIs überprüfen, finden Sie nur die remove-Methode, es gibt keine add-Methode. Es gibt einen Grund dafür und Sie können Javadoc dafür überprüfen. Kommen wir nun zum Punkt, wie man das neu hinzugefügte Element iteriert.
HashMap
. So iterieren Sie eines und ändern das andere Map
. Map
hinzugefügt und entfernt werden müssen, würde ich gerne ListIterator
verwenden [das ist anders als normal Iterator
]. keyset
von Map1 erhalten und sie in eine Liste mit ArrayList(Collection<? extends E> c)
umwandeln. ListIterator
von List
erhalten, die in Schritt 3 erstellt wurden, und Elemente in ListIterator
sowie in Map2 hinzufügen und entfernen [Beachten Sie, dass Sie hinzufügen müssen, entfernen Sie beide in ListIterator
und Map2]. Ein Beispielcode-Ausschnitt zum Entfernen eines Elements aus der Karte ist unten angegeben.
%Vor%Wenn Ihr Code viel hinzufügt und entfernt, können Sie einfach ConcurrentHashMap verwenden. ConcurrentHashMap