# foreach Schleife



## GilbertGrape (14. Okt 2008)

Hallo,

Ich versuche mal, mein Problem ganz einfach zu erläutern.
Ich möchte aus einer List gleiche Einträge raussuchen.
Das heißt, ich nehme den ersten Eintrag und suche alle gleichen Einträge.
Da ich die ja nur einmal haben möchte, lösche ich sie dann aus der Liste.

Ich dachte, dass die foreach-Schleife (heißt die auch so in Java?) dann so "schlau" ist und einfach zum nächsten noch vorhandenen Eintrag in der Liste geht, aber so gehts anscheinend nicht. 

Hier mein Code:


```
public static void main(String... args) {
			   List<String> list = new ArrayList<String>();
			   List<String> remove = new ArrayList<String>();
			   list.add("Hallo1");
			   list.add("Hallo1");
			   list.add("Hallo2");
			   list.add("Hallo3");
			   list.add("Hallo4");
			   list.add("Hallo5");
			   
			   for (String erster : list){
				   remove.clear();
				   for (String zweiter : list){
					   if (erster.equals(zweiter)){
						   remove.add(zweiter);
					   }
				   }
				   list.removeAll(remove);
			   }
		   }
```

Exception:
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
	at java.util.AbstractList$Itr.next(Unknown Source)

Die Exception kommt, wenn er das 2. Mal zum ersten for kommt.


----------



## SlaterB (14. Okt 2008)

streiche Zeile 13 und vertausche Zeile 19 und 20

-------

während du über eine Liste iterierst, darst du nichts daraus löschen

-----

kürzer wäre 
list = new ArrayList<String>(new HashSet(list));


----------



## GilbertGrape (14. Okt 2008)

Danke, aber so einfach ist es leider nicht.
Die Einträge sind nicht wirklich gleich, haben nur einen gleichen Schlüssel. Ich will die Einträge quasi gruppieren.
Ich schreibe "Hallo1" und "Hallo1" (sagen wir mal, das wären Schlüssel  ) raus. Beim nächsten Durchlauf ist er dann beim zweiten "Hallo1" und ich hab die gleiche Liste nochmal. Deshalb wollte ich die Einträge eben löschen, nachdem ich alle Einträge zu einem Schlüssel gefunden hab.

Sorry, dass ich das Beispiel so blöd gewählt hab.


----------



## SlaterB (14. Okt 2008)

falls da noch eine Frage drinsteht, so musst du sie für mich neuformulieren 
zumindest deinen Fehler habe ich ja erklärt


----------



## GilbertGrape (14. Okt 2008)

Also gut:
Ich möchte Elemente einer Liste nach einem bestimmten Merkmal gruppieren. Wie mach ich das am Besten? 
Wenn ich zum Beispiel Objekte haben, die jeweils ein Attribut Datum haben. Ich möchte jetzt, dass in einer Liste alle Elemente mit einem Datum stehen und das natürlich für alle vorkommenden Daten.


----------



## GilbertGrape (14. Okt 2008)

Ich könnte natürlich in jedem Durchlauf abfragen, ob ich dieses Datum schonmal hatte, aber ich dachte, dass das nicht so schön und eben auch mehr Aufwand ist (für den Rechner, nicht für mich  )


----------



## SlaterB (14. Okt 2008)

Liste anlegen und einfügen,
das hast du doch anscheinend schon?

nur das Entfernen darfst du während des Durchlaufs nicht machen,
muss das denn dabei passieren? damit die Listen nicht mehrfach erzeugt werden?


mal was anderes:
verwende eine Liste X besonderer Elemente sowie eine Map Element -> Liste

dann durchläufst du die Ursprungsliste nur genau einmal,
für jedes Element Y durchläufst du die Liste X, wenn nicht gefunden, dann füge Y in X ein sowie im die Map einen neuen Eintrag Y -> neue Liste mit Y drin

falls doch gefunden dann hole dir aus der Map die passende bereits vorhandene Liste und füge dort auch Y ein,

so hast du am Ende in X ein paar Elemente, die Gruppenköpfe,
und in der Map jeweils die Liste der zugehörigen Elemente


falls alle Elemente ordentlich HashCode implementieren passend zur Gruppenzugehörigkeit, dann reicht auch nur die Map


----------



## Michael... (14. Okt 2008)

Zunächst: Weg mit der for each Schleife (ich kann sie mit meiner version 1.4.2 auch nicht nutzen;-))
Und her mit einer normalen for Schleife, die allerdings vom Listenende anfängt zu iterieren und dann wenn der aktuelle index bereits in der Liste enthalten ist diesen löschen.


----------



## GilbertGrape (14. Okt 2008)

Danke SlaterB! Ich lass mir das mal durch den Kopf gehen und meld mich dann vielleicht morgen nochmal!

Michael, ich glaube, du hast nicht ganz verstanden was ich meinte. Und sind alle Sachen schlecht, die seit Java 1.4.2 dazu gekommen sind?


----------



## SlaterB (14. Okt 2008)

zumindest würde die alte Variante die Exception verhindern, das ist doch schonmal was,

aber auch damals war es nicht die feine Art, eine Liste zu ändern, die gerade durchlaufen wird


----------



## Michael... (14. Okt 2008)

GilbertGrape hat gesagt.:
			
		

> ich glaube, du hast nicht ganz verstanden was ich meinte.


Ich hab verstanden Du willst doppelte/ähnliche Einträge aus einer Liste löschen. Deswegen mein Hinweis, wenn man beim durchlaufen einer Liste Einträge löschen will, sollte man die Liste von hinten nach vorne durchlaufen, dann hat man weniger Problemen mit dem Index.


			
				GilbertGrape hat gesagt.:
			
		

> Und sind alle Sachen schlecht, die seit Java 1.4.2 dazu gekommen sind?


Ist ja nur der Neid, dass mir so manche Funktion aus höheren Versionen nicht zur Verfügung steht. ;-(


----------



## GilbertGrape (15. Okt 2008)

Michael... hat gesagt.:
			
		

> Ich hab verstanden Du willst doppelte/ähnliche Einträge aus einer Liste löschen. Deswegen mein Hinweis, wenn man beim durchlaufen einer Liste Einträge löschen will, sollte man die Liste von hinten nach vorne durchlaufen, dann hat man weniger Problemen mit dem Index.



Es ist ja nicht mein Hauptziel, die doppelten Einträge zu löschen. Ich wollte alle Einträge, die den gleichen Schlüssel besitzen gruppieren. Das Löschen hatte ich nur gemacht, damit ich den gleichen Schlüssel nicht nochmal gruppiere.

PS: Warum meldest du dich hier eigentlich nicht an? Ich hab doch inzwischen schon häufiger von dir gelesen oder waren das immer andere?


----------



## GilbertGrape (15. Okt 2008)

@SlaterB: Danke nochmal für den Tip mit der Map. Habs jetzt damit hingekriegt!


----------

