# Collection während Iteration verändern



## banshee (25. Jul 2009)

Hallo,

ich würde gerne Elemente aus einer Collection löschen, während ich sie durchlaufe. Das führt natürlich dazu, dass der Iterator ins Leere greift und eine Exception wirft. Bleibt mir da keine andere Möglichkeit, als irgendwie ein bool-Array anzulegen und die Collection danach bearbeiten oder kann ich sie z.B. irgendwie rückwärts durchlaufen und immer das hinterste Element löschen?


----------



## sliwalker (25. Jul 2009)

Merk Dir doch die Objekte in einer anderen Collection/List.
Dann kannste danach du4rch diese iterieren und alles aus der ersten Collection löschen.

Sauberer ist natürlich wenn die Objekte in der Collection ein Attribut "removed" oder so hätten.
Aber das bekommst nachträglich natürlich nicht mehr rein, oder?


----------



## Painii (25. Jul 2009)

evtl. unsauber?


```
boolean ende;
do{
try{
 for(Element e:collection)if(/*e soll entfernt werden*/)collection.remove(e);
 ende=true;
}catch(/*Exception des Iterators nehm ich an? (ConcurrentModificationException*/){
 ende=false;
}
}while(!ende)
```
Durchlaufe die while-schleife, wenn ein element entfernt wird sollte dein Iterator eine Exception werfen -> du durchläufst die while-schleife nochmal, ein neuer Iterator wird gebaut wo du dann wieder ein element rausnimmst.
Wenn der Iterator einmal durchkommt hat er kein Element mehr löschen müssen -> die while-schleife kann beendet werden.


----------



## SchonWiederFred (25. Jul 2009)

banshee hat gesagt.:


> ich würde gerne Elemente aus einer Collection löschen, während ich sie durchlaufe.


Du musst die Collection auf die Java 1.4 Weise durchlaufen, also explizit einen Iterator anfordern und diesen fortbewegen.
Dann musst Du remove auf dem Iterator aufrufen, nicht auf der Collection. Hier ist ein Beispiel.

```
public static void removeOdd(Collection<Integer> collection)
{
	Iterator<Integer> it = collection.iterator();
	while (it.hasNext())
	{
		Integer i = it.next();
		if ((i & 1) != 0)
		{
			it.remove(); // <--- wichtig!
		}
	}
}
```
Und ganz allgemein ausgedrückt (Element und shouldBeRemoved durch konkrete Dinge ersetzen):

```
public static void removeElements(Collection<Element> collection)
{
	Iterator<Element> it = collection.iterator();
	while (it.hasNext())
	{
		Element e = it.next();
		if (shouldBeRemoved(e))
		{
			it.remove(); // <--- wichtig!
		}
	}
}
```


----------



## banshee (2. Aug 2009)

Hallo,

das gleiche Problem habe ich jetzt mit JLists. Ich möchste alle selektierten Elemente löschen und


```
for(index i : liste.getSelectedIndices())
((DefaultListModel)liste.getModel()).remove(i);
```

löscht sich die Elemente dann wieder selbst vor der Nase weg. Gibt es da eine andere saubere Möglichkeit oder muss ich das Array dann in ein Objekt umwandeln, dass man mit einem Iterator durchlaufen kann?


----------



## Landei (2. Aug 2009)

Wenn ich was aus einer Liste löschen muss, mache ich das immer rückwärts, weil ich dann nie Probleme mit dem "Nachrutschen" habe:

```
List<X> list = getXList();
for(int i = list.size()-1; i >= 0; i--) {
   X x = list.get(i);
   if(loeschen(x)) {
       list.remove(i);
   }
}
```


----------



## banshee (7. Aug 2009)

okay, leider das nächste Problem gleicher Art.

Diesmal muss ich aus einem eigenen DatenModell löschen, das intern eine HashMap verwaltet. Das Problem dabei ist, dass ich nicht iterator.remove aufrufen kann, sondern auf die eigene remove-Funktion ausweichen muss, weil da noch mehr gelöscht werden muss, als nur der Eintrag aus der HashMap.

Ich kann allerdings auch nicht die Technik des rückwärts Durchlaufens anwenden, weil ich eine Collection von DataEntrys zurückbekomme, die ich nicht in ein "manuell iterierbares" Format casten kann (oder ich bin zu doof dazu, kann natürlich auch sein )


----------



## André Uhres (8. Aug 2009)

Ich bin nicht sicher, ob du das meinst, aber wir können die Keys in ein Array setzen, das wir dann rückwärts durchlaufen:

```
Object[] keys = map.keySet().toArray();
for (int i = keys.length-1; i > -1; i--) {
    map.remove(keys[i]);
}
```


----------

