# Bestimmte Objekte einer Liste hinzufügen



## internet (28. Sep 2011)

Hallo zusammen,
Ich habe ein Textfile.
Ich habe eine Liste (Linked List).
Ich möchte in diese Liste Objekte speichern.

Nun möchte ich aber überprüfen, ob ein bestimmter String schon in der Liste vorhanden ist.
Zum Beispiel:
Ich habe einige Personen.
Ist in der Liste bereits eine Person, die den Namen "Meier" hat, dann soll dieses Objekt nicht der Liste hinzugefügt werden.

Wie kann ich das machen?


----------



## neela (28. Sep 2011)

lass dir einfach aus der liste die entsprechende Objekte ausgeben wenn nix zurück kommt is die person noch nicht vorhanden

```
(Person)list.get("Maier" )
if (person=null){
//ist sie noch nicht vorhanden
}
```


----------



## faetzminator (28. Sep 2011)

Oder List (Java Platform SE 6). Macht das gleiche, ist etwas schöner.
Warum arbeitest du in diesem Fall nicht mit einem Set?


----------



## nillehammer (28. Sep 2011)

neela hat gesagt.:
			
		

> (Person)list.get("Maier" )
> if (person=null){
> //ist sie noch nicht vorhanden
> }


Das ist Blödsinn. Bei List gibt es so eine Methode nicht. Get geht nur über den Index.

Wenn Du Personen in dieser List speicherst, musst Du equals() und hashCode() der Klasse Person so überschreiben, dass sie bei Namensgleichheit true/denselben hash Code zurück liefern. Dann kannst du die Methode contains(..) des List-Interface verwenden.


----------



## bygones (28. Sep 2011)

nillehammer hat gesagt.:


> Das ist Blödsinn. Bei List gibt es so eine Methode nicht. Get geht nur über den Index.
> 
> Wenn Du Personen in dieser List speicherst, musst Du equals() und hashCode() der Klasse Person so überschreiben, dass sie bei Namensgleichheit true/denselben hash Code zurück liefern. Dann kannst du die Methode contains(..) des List-Interface verwenden.



was aber auch nur sinn macht, wenn das zu suchende element ebenso vom selben Typ ist. Wenn man nur per String auf etwas sucht und nicht gleich das ganze objekt erzeugen will.

Bei einer LinkedList waere ein indexbasierter zugriff so und so eklatant, einfach ueber die Liste iterieren und den gewuenschten Vergleich anstellen


----------



## obb (28. Sep 2011)

Um das ganze noch zu präzisieren: Ich halte den Beitrag von *faetzminator* ebenfalls für eleganter. Da Du aber wahrscheinlich Objekte vom Typ 
	
	
	
	





```
Person
```
 in der Liste speicherst, ist damit noch nicht alles getan.​Wenn Du Dir die Beschreibung der contains-Methode etwas genauer anschaust, siehst Du, dass das Dein Objekt über die equals-Methode mit den Objekten der Liste verglichen wird. Die contains-Methode liefert also dann 
	
	
	
	





```
true
```
 zurück, wenn 
	
	
	
	





```
deinObjekt.equals(listenobjekt)
```
 ebenfalls 
	
	
	
	





```
true
```
 zurückgibt.​Was also noch zu tun bleibt, ist die equals-Methode in Deiner Klasse 
	
	
	
	





```
Person
```
 zu überschreiben. Hier mal ein KSKB dazu:

```
public class Person {
	String name;
	
	public Person(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {
		Person theOtherPerson = (Person) obj;
		if(this.name.equals(theOtherPerson.name))
			return true;
		else
			return false;
	}
	
	public static void main(String[] args) {
		Person p1 = new Person("Maier");
		Person p2 = new Person("Maier");
		Person p3 = new Person("Schmitz");
		
		System.out.println("Maier.equals(Schmitz): " + p1.equals(p3));
		System.out.println("Maier.equals(Maier): " + p1.equals(p2));
	}
}
```
Jetzt bist du fertig und kannst Personen aus deiner liste mit anderen Personen über die contains-Methode vergleichen.​Noch etwas: Da ich in meinem Beispiel in der equals-Methode die Objekte zu 
	
	
	
	





```
Person
```
-Objekten caste, könntest Du in Schwierigkeiten kommen, wenn Du in der Liste Objekte mit unterschiedlichen Datentypen speicherst. Sollte das der Fall sein, muss die eqals-Methode vielleicht ein bisschen komplizierter aufgezogen werden. Ich halte es aber in den meisten Fällen für sehr ratsam, in einer Liste nur Objekte von einem Datentyp zu speichern (
	
	
	
	





```
LinkedList<Person>
```
). Wenn Du also Objekte mit unterschiedlichen Datentypen in der Liste speicherst, dann solltest Du Dein Design vielleicht nochmal überdenken.​


----------



## faetzminator (28. Sep 2011)

Ich würde equals etwa so implementieren (mit der Klasse [c]Foo[/c] und dem Feld [c]field[/c]):

```
@Override
public boolean equals(Object obj) {
    if (this == obj) { // für die Geschwindigkeit!
        return true;
    }
    if (obj == null || getClass() != obj.getClass()) { // wem ein instanceof lieber ist, kann natürlich auch das verwenden ;)
        return false;
    }
    Foo other = (Foo) obj;
    if (field == null) {
        return other.field == null;
    }
    return field.equals(other.field);
}
```
Da fliegen keine NPE's und ClassCastExceptions 

Edit:
Da man anscheinend in vielen Projekten die Apache Commons verwendet, kann man natürlich auch die jeweiligen Methoden derer Libs verwenden. Also z.B. für Strings ein [c]return StringUtils.equals(field, other.field)[/c].


----------



## obb (28. Sep 2011)

Ich find es gut wenn manchmal solche Sachen wie NPEs und ClassCastExceptions fliegen. Da wird einem meistens klar, dass man beim Coden gerade ziemlichen Mist gebaut hat . Ansonsten find ich die Methode top! Gerade, wenn man Objekte von anderen benutzt und keine Ahnung hat, was da wieder alles verbrochen wurde .


----------



## faetzminator (29. Sep 2011)

obb hat gesagt.:


> Ich find es gut wenn manchmal solche Sachen wie NPEs und ClassCastExceptions fliegen [...]



Ich fände es besser, wenn mit Generics oder einer anderen Magie die Signatur irgendwie auf den Typen eingeschränkt werden könnte. Ich hab sowas vor einiger Zeit mit Generics versucht, aber leider bring ich es ohne Parametrisierung ([c]SomeAction extends Action<SomeBean, SomeController, ...>[/c]) nicht hin.


----------



## maki (29. Sep 2011)

obb hat gesagt.:


> Ich find es gut wenn manchmal solche Sachen wie NPEs und ClassCastExceptions fliegen. Da wird einem meistens klar, dass man beim Coden gerade ziemlichen Mist gebaut hat .


Ich finde es besser, wenn Verträge einghalten werden. 

equals darf weder eine NPE noch eine ClassCastException werfen laut API, dafür sollte man aber auch die hashcode Methode überschreiben falls man sich schon an equals wagt 

Das verhalten von Standardmethoden soweit abzuändern ist sicher keine gute Idee...

Unittests sind gut geeignet um herauszufinden ob man ziemlichen Mist gebaut hat


----------



## obb (29. Sep 2011)

> Ich finde es besser, wenn Verträge einghalten werden.
> 
> equals darf weder eine NPE noch eine ClassCastException werfen laut API, dafür sollte man aber auch die hashcode Methode überschreiben falls man sich schon an equals wagt


Stimmt! Da habe ich mal wieder nicht genau nachgelesen. Ansonsten halte ich es für extrem sinnvoll übergaben von 
	
	
	
	





```
null
```
 mit einer Exception zu quittieren, da das ein eindeutiger Hinweis auf Fehlverhalten eines Systems oder Pfusch ist.


----------



## faetzminator (30. Sep 2011)

obb hat gesagt.:


> Ansonsten halte ich es für extrem sinnvoll übergaben von
> 
> 
> 
> ...



Nicht zwingend. Es gibt immer wieder Situationen, in denen [c]null[/c] ebenfalls ein valider Status ist. Nehmen wir String als Beispiel: Ist für dich "" (leer) das gleiche wie null ("nicht vorhanden")? Für mich nicht.


----------



## maki (30. Sep 2011)

obb hat gesagt.:


> Ansonsten halte ich es für extrem sinnvoll übergaben von
> 
> 
> 
> ...


Das sehe ich auch so.

null sollte man als validen returnwert vermeiden falls möglich imho, alternativen sind zB. das sog. NullObject, falls möglich.


----------



## internet (30. Sep 2011)

So.
					Ich habe jetzt mal die equals - Methode in der Klasse implementiert.
					Sofern die ID gleich ist, dann fügt er diese auch nicht ein, ABER:

					Bsp: 
					Das erste Objekt in der Liste ist: 12345
					Die id ist 12345
					=> Wird nicht eingefügt

					Ist nun das Objekt in der Liste: 12345
					Die Id 54321
					=> Wird eingefügt

					ABER:
					Ist das Objekt nun in der Liste 54321 
					Die ID 12345
					=> Wird diese ID trotzdem eingefügt, obwohl sie schon in der Liste ist.

					Das liegt daran, dass er ja einzeln die Objekte prüft.
					Also erst das erste Element in der Liste usw.

					Wie kann das aber anstellen, dass er mir sozusagen alle Objekte in der Liste durchgeht und prüft, ob ein Element mit dem Attribut (String) zB: 12345
					schon exisitert ?



Das ist der bisherige Code:
Er geht also Zeile für Zeile durch


```
while (sZeile != null) {
				sZeile = bReader.readLine();			

				try {
					// Nur Zeilen suchen mit "id"
					if (suchString != null) {
						if (sZeile.contains(suchString)) {


							// Sofern die  Liste leer ist, dann erstes Objekt hinzufügen
							if(idList.isEmpty()){
								Session session = new Session(id);
								idList.add(session);
							}				
							
							// Prüfen, ob es die ID schon gibt in der Liste gibt
							// Wenn nein, dann hinzuzufügen
							for(int i=0; i<idList.size();i++){	
								
								try{
									if(!idList.get(i).getSessionId().equals(id)){									
										Session session = new Session(id);
										idList.add(session);
									}
										
								}
								catch(NullPointerException e){
									e.printStackTrace();
								}
							}
						}
					}
```


----------



## faetzminator (30. Sep 2011)

*** wird dir helfen.

Edit: ich sehe gerade, dass ich das hier bereits mit dem ersten Post beantwortet habe - darum die ***.


----------



## obb (30. Sep 2011)

Ich glaube, da haben wir uns etwas falsch verstanden. Schau Dir nochmal die contains-Methode im Interface List an. Die ruft schon für jedes Objekt in Deiner Liste die equals-Methode auf. Was Dir zu tun bleibt, ist die equals-Methode in Deiner Klasse "Session" zu überschreiben. Danach kannst Du folgenden Block

```
// Prüfen, ob es die ID schon gibt in der Liste gibt
// Wenn nein, dann hinzuzufügen
for(int i=0; i<idList.size();i++) {	
	try {
		if(!idList.get(i).getSessionId().equals(id)) {									
			Session session = new Session(id);
			idList.add(session);
		}								
	}
	catch(NullPointerException e) {
		e.printStackTrace();
	}
}
```
abändern in

```
Session session = new Session(id);
if(!idList.contains(session))
	idList.add(session);
```
Dadurch müsste Dein Problem gelöst werden.
Noch etwas: Wenn Du Code einfügst, dann packe ihn bitte in 
	
	
	
	





```
-Tags und rücke ihn sinnvoll ein, damit er übersichtlicher wird.
```


----------



## obb (30. Sep 2011)

> Nicht zwingend. Es gibt immer wieder Situationen, in denen
> 
> 
> 
> ...


Für mich ist das natürlich auch nicht das gleiche. Trotzdem rechtfertigt das nicht, 
	
	
	
	





```
null
```
 an irgendwelche Methoden zu übergeben. Die lassen sich nämlich so überladen, dass sie auch ohne Argumente funktionieren.


----------

