# ArrayListe :Doppelte entfernen -> keine Referenzen



## auxilium (3. Mrz 2008)

hallo, ich habe eine ArrayListe, aus der ich gerne doppelte Einträge entfernen möchte.
Die Arraylist sieht so aus, dass sich in jeder Obejekte befinden.

Dabei kann es vorkommen, dass bestimmte Variablen dieser Objekte identisch sind.

Wenn das so ist, dann gilt eine als doppelte, die ausgefiltert werden kann.

Ich würde das jetzt mit einer schleife lösen und alles überprüfen, aber da gibt es doch bestimmt eine elegantere Lösung?


----------



## maki (3. Mrz 2008)

Elegant?

Schon mal was von Set gehört?

Dann solltest du aber auch klarstellen, was "Gleichheit" bei deinen Objekten bedeutet.
Wenn es mehr ist als nur Referentielle Gleichheit (zB ref1 == ref2), dann musst du equals und hashcode überschreiben.


----------



## SlaterB (3. Mrz 2008)

"bestimmte Variablen dieser Objekte identisch" -> "gilt eine [von beiden] als doppelte"
klingt für mich sehr klar


----------



## quippy (4. Mrz 2008)

Mmmh, wie wäre es, die ArrayList neu aufzubauen und via "contains" dabei zu prüfen, ob das Element schon da ist? Ist zwar Speicherintensiver, aber dann mußt Du selbst nur eine Schleife bauen.

Alternative: Sortieren mit z.B. QuickSort. Die gleichen stehen dann nebeneinander-mh, oder Du mißbrauchst den Quicksort-Algorithmus dafür, um die gleichen zu finden.

Die Optimierung ist halt, jeden mit jedem zu vergleichen, aber Vergleichspaarungen nicht doppelt zu haben (also, wenn A!=B wird auch B!=A sein, also kann der zweite Vergleich ausbleiben)


----------



## JavaFred (4. Mrz 2008)

auxilium hat gesagt.:
			
		

> da gibt es doch bestimmt eine elegantere Lösung?


Wenn Deine Objekte equals und hashCode korrekt überschreiben, kannst Du folgende Hilfsmethode verwenden:


```
public static <T> ArrayList<T> ohneDoppelte(Collection<T> list)
{
	return new ArrayList<T>(new HashSet<T>(list));
}
```
Es werden einfach alle Einträge aus der Originalliste in ein HashSet gepackt (dabei werden Duplikate ignoriert), und dann landen wiederum alle Einträge aus diesem HashSet in einer neuen ArrayList, welche zurückgegeben wird.


----------



## Marco13 (4. Mrz 2008)

.... genau so   und mit einer LinkedHashSet bleibt sogar die Reihenfolge erhalten


----------



## auxilium (4. Mrz 2008)

ah vielen dank


----------



## zarr (9. Dez 2009)

quippy hat gesagt.:


> Mmmh, wie wäre es, die ArrayList neu aufzubauen und via "contains" dabei zu prüfen, ob das Element schon da ist? Ist zwar Speicherintensiver, aber dann mußt Du selbst nur eine Schleife bauen.
> 
> Alternative: Sortieren mit z.B. QuickSort. Die gleichen stehen dann nebeneinander-mh, oder Du mißbrauchst den Quicksort-Algorithmus dafür, um die gleichen zu finden.
> 
> Die Optimierung ist halt, jeden mit jedem zu vergleichen, aber Vergleichspaarungen nicht doppelt zu haben (also, wenn A!=B wird auch B!=A sein, also kann der zweite Vergleich ausbleiben)


hey genau diese problem habe ich auch das bei mir immer AB und BA rauskommt wie kann ich denn nur machen das AB oder nur BA rauskommt?


----------



## Sekundentakt (9. Dez 2009)

Hey,

ganz einfach:
Du vergleichst nur noch Objekte die größer als das vorherige gewesen sind.
Beispiel:

Die Objekte A, B, C,

A → B
A → C
B → C
c → nichts

wobei "→" soviel wie "mit" heißt​
Als rein rechnerischen Ansatz ergibt sich darauß eine *Anzahl* von Vergleichen, die in Psuedocode so berechnet werden kann:

offeneRechnungen = Elementanzahl;

for(i = 1; i < Elementanzahl; i++
{
     offeneRechnungen = offeneRechnungen - i;
}


----------



## maki (9. Dez 2009)

> 04.03.2008, 16:44


:lol::lol::lol:


----------



## Sekundentakt (9. Dez 2009)

maki hat gesagt.:


> :lol::lol::lol:



Äh, ja :reflect:


----------



## zarr (10. Dez 2009)

Sekundentakt hat gesagt.:


> Hey,
> 
> ganz einfach:
> Du vergleichst nur noch Objekte die größer als das vorherige gewesen sind.
> ...




```
Collections.sort(mitarbeiter1);
	 				for (int i=0; i<mitarbeiter1.size(); i++) 
	 				{
	 		            for (int k=i+1; k<mitarbeiter1.size(); k++)
	 		            {
	 		                if (mitarbeiter1.get(i).hasSameName(mitarbeiter1.get(k))) 
	 		                {  	
	 		                   		System.out.println(mitarbeiter1.get(i).getName()+" "+sdf.format(mitarbeiter1.get(i).getGeburtstag()));
	 		                   		System.out.println(mitarbeiter1.get(k).getName()+" "+sdf.format(mitarbeiter1.get(k).getGeburtstag()));    			 		                   		                    
	 		              	}	 		                
	 		            }
	 				}
```
ja so hab ich des bei mir stehn nur des is ja falsch ich komm da einfach nicht mehr weiter.... :-(


----------



## Ebenius (10. Dez 2009)

maki hat gesagt.:


> :lol::lol::lol:


Ich hatte es auch dreimal lesen müssen, bis ich verstanden hatte, dass nur die letzte Zeile von zarrs Beitrag sein Text war und der Rest ein Zitat. Er hat also eine Frage die sich anschließt. Hab den Beitrag mal editiert, bevor noch einer sich wundert.

@zarr: Bitte Zitate ordentlich kennzeichnen! Am besten den "zitieren"-Knopf benutzen!

Ebenius


----------



## Ebenius (10. Dez 2009)

Und Deine Mitarbeiter-Einträge sind definitiv vergleichbar nach deren Namen (Comparable-Interface und entsprechende compareTo(...)-Methode)?

BTW: Wenn man schon sortiert, dann braucht man auch nur direkte Nachbarn auf Gleichheit prüfen. Sobald einmal [c]false[/c] kommt, kann man in die äußere Schleife zurück.

Ebenius


----------



## zarr (10. Dez 2009)

ok also das is in meiner Mitarbeiter


```
...
    public boolean hasSameName(Mitarbeiter mitarbeiter) 
    {
        return this.name.equalsIgnoreCase(mitarbeiter.getName());
    }

	
	 public int compareTo(Mitarbeiter o) 
	 {
	   	return ((String)name).compareTo((String)o.name);	
	 }
}
```

... hmm ok aber wenn ich 2 imemr vergleiche dann vergleicht er mir ja A mit B und B mit A also doppelt!
oder komm ich da grad nicht mit?

PS: Ich weiß schon sorry wegen dem Zitat is was daneben gegangen ;-) *UPPS* ^^


----------



## eRaaaa (10. Dez 2009)

```
public int compareTo(Mitarbeiter o) 
     {
        return ((String)name).compareTo((String)o.name);    
     }
```

meinst du vllt:

```
public int compareTo(Mitarbeiter o) 
     {
        return this.name.compareTo(o.name);    
     }
```

?


----------



## zarr (10. Dez 2009)

eRaaaa hat gesagt.:


> ```
> public int compareTo(Mitarbeiter o)
> {
> return ((String)name).compareTo((String)o.name);
> ...



ja ist doch das gleiche halt ohne String ^^


----------



## Ebenius (10. Dez 2009)

Also Du musst schon nach den selben Kriterien sortieren... [c]hasSameName()[/c] ist case*In*Sensitive... Deine [c]compareTo()[/c]-Methode nicht.

Wie geht's denn schief?

Ebenius


----------



## zarr (10. Dez 2009)

Also mein Problem ist es das wenn ich z.b

Max Muster 11.11.1111
Test Tester 12.12.1212
Max Muster 13.10.1010
Hansi Hinterseher 05.05.0505
Max Muster 01.01.0101

eingebe kommt 
als ergebnis heraus

Max Muster 11.11.1111
Max Muster 13.10.1010

Max Muster 11.11.1111
Max Muster 01.01.0101

Max Muster 01.01.0101
Max Muster 13.10.1010

also immer doppelt A und B und B und A verstehst du das?


----------



## Ebenius (10. Dez 2009)

Hä, was machst du da? Du gibst die jeweils miteinander verglichenen mit gleichem Namen aus. Natürlich gibt es bei drei gleichen Namen (in deinem Beispiel A, C, E) die drei namensgleichen Vergleiche A gegen C, A gegen E und C gegen E. Da ist kein "A gg. C / C gg. A -Vergleich dabei. Was willst Du eigentlich tun?

Ebenius


----------



## zarr (10. Dez 2009)

ich möche ausgeben mitarbeiter mit gleichen namen. ^^
nur wie gesagt es kommt alles doppelt und ich steh grad aufn schlauch ^^


----------



## Ebenius (10. Dez 2009)

Dann schmeiß doch einfach Zeile 9 raus. ;-)

Ebenius


----------



## Spacerat (10. Dez 2009)

maki hat gesagt.:


> Wenn es mehr ist als nur Referentielle Gleichheit (zB ref1 == ref2), dann musst du equals und hashcode überschreiben.


Ich wollte dieses hier noch mal erwähnt haben... Ich fürchte daran liegts.
@Edit: Hab' grad' deine Sortiermethode gefunden... dort heisst es:
	
	
	
	





```
for (int i=0; i<mitarbeiter1.size(); i++)
```
Das müsste doch eigentlich
	
	
	
	





```
for (int i=0; i<mitarbeiter1.size() - 1; i++)
```
heissen, oder sehe ich das falsch? Alles in allem sehe ich da auch keinen sort-algo


----------



## Ebenius (10. Dez 2009)

Spacerat, es liegt daran, dass er die beiden kandidaten ausgibt die mit einander verglichen werden. also 1. A/C, 2. A/E und 3. C/E. Er will aber distinkt alle namensgleichen ausgeben...

Mach's doch einfach so: 
	
	
	
	





```
Collections.sort(mitarbeiter1);
                    Mitarbeiter vorgaenger = null;
                    int namensgleicheVorganger = 0;
                    for (Mitarbeiter m : mitarbeiter1) {
                        if (vorgaenger != null) {
                          if (m.hasSameName(vorgaenger)) {
                            if (++namensgleicheVorganger == 1) {
                              System.out.println(vorgaenger.getName());
                            }
                            System.out.println(m.getName());
                          } else {
                            namensgleicheVorganger = 0;
                          }
                        }
                        vorgaenger = m;
                      }
                    }
```
Code im Browser getippt...

Anmerkung: Das funktioniert aber nur mit groß-/kleinschreibungsgleichen Mitarbeiternamen. Du musst [c]compareTo(...)[/c] noch anpassen, dass die Methode [c]String.compareToIgnoreCase(...)[/c] benutzt.

Ebenius


----------



## zarr (10. Dez 2009)

Ebenius hat gesagt.:


> Spacerat, es liegt daran, dass er die beiden kandidaten ausgibt die mit einander verglichen werden. also 1. A/C, 2. A/E und 3. C/E. Er will aber distinkt alle namensgleichen ausgeben...
> 
> Mach's doch einfach so:
> 
> ...



HEYYYYYY danke super klasse genau das wollte ich die ganze zeit danke super echt ;-) :applaus:


```
Collections.sort(mitarbeiter1);
	                    Mitarbeiter vorgaenger = null;
	                    int namensgleicheVorganger = 0;
	                    for (Mitarbeiter m : mitarbeiter1) {
	                        if (vorgaenger != null) {
	                          if (m.hasSameName(vorgaenger)) {
	                            if (++namensgleicheVorganger == 1) {
	                              System.out.println(vorgaenger.getName()+" "+sdf.format(vorgaenger.getGeburtstag()));
	                            }
	                            System.out.println(m.getName()+" "+sdf.format(m.getGeburtstag()));
	                          } else {
	                            namensgleicheVorganger = 0;
	                          }
	                        }
	                        vorgaenger = m;
	                      }
	                    }
```


----------



## Ebenius (10. Dez 2009)

Gut, dann ist das Thema wohl erledigt. Den Danke-Knopf findest Du unter meinem Beitrag. :lol:



Spacerat hat gesagt.:


> Alles in allem sehe ich da auch keinen sort-algo


[c]Collections.sort(...)[/c], Zeile 1.

Ebenius


----------



## Spacerat (10. Dez 2009)

Da muss man aber genauer hinsehen, sonst übersieht man da was. Ich hab' das wegen dieser tiefen Einrückung iwie glatt für 'ne Methode [c]sort()[/c] gehalten, die eine Collection zurückliefert. Dabei habe ich auch weniger auf *Punkt* und *Semikolon* geachtet. Bei dir dagegen siehts schon klarer aus. Was gut formatierter Quelltext so alles ausmacht...


----------

