Wie kann man TreeMap während der Iteration entfernen und Elemente hinzufügen?

8

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

    
Mahmoud Hanafy 19.05.2013, 16:46
quelle

5 Antworten

7

Erklärung, warum es ConcurrentModificationException

verursacht hat %Vor%

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%     
Subhrajyoti Majumder 19.05.2013, 17:10
quelle
2

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).

    
Bohemian 20.05.2013 04:39
quelle
1

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.

  1. Erstellen Sie eine Kopie Ihres HashMap . So iterieren Sie eines und ändern das andere Map .
  2. Da sowohl Elemente in Map hinzugefügt und entfernt werden müssen, würde ich gerne ListIterator verwenden [das ist anders als normal Iterator ].
  3. Ich werde die keyset von Map1 erhalten und sie in eine Liste mit ArrayList(Collection<? extends E> c) umwandeln.
  4. Jetzt werde ich 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].
Lokesh 19.05.2013 16:56
quelle
1

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

    
SamDJava 15.09.2014 18:12
quelle
0

Weil Sie das nicht können.

Eine einfache Lösung besteht darin, eine andere temporäre Karte zu verwenden, in die Sie die gewünschten Werte eingeben und schließlich Zeiger mit der ursprünglichen wechseln (z. B. Map = newMap)

    
Ahmad 19.05.2013 17:03
quelle

Tags und Links