Bestimmte Objekte einer Liste hinzufügen

internet

Top Contributor
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?
 
lass dir einfach aus der liste die entsprechende Objekte ausgeben wenn nix zurück kommt is die person noch nicht vorhanden
Java:
(Person)list.get("Maier" )
if (person=null){
//ist sie noch nicht vorhanden
}
 
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.
 
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
 
Um das ganze noch zu präzisieren: Ich halte den Beitrag von faetzminator ebenfalls für eleganter. Da Du aber wahrscheinlich Objekte vom Typ
Code:
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
Code:
true
zurück, wenn
Code:
deinObjekt.equals(listenobjekt)
ebenfalls
Code:
true
zurückgibt.​
Was also noch zu tun bleibt, ist die equals-Methode in Deiner Klasse
Code:
Person
zu überschreiben. Hier mal ein KSKB dazu:
Java:
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
Code:
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 (
Code:
LinkedList<Person>
). Wenn Du also Objekte mit unterschiedlichen Datentypen in der Liste speicherst, dann solltest Du Dein Design vielleicht nochmal überdenken.​
 
Zuletzt bearbeitet:
Ich würde equals etwa so implementieren (mit der Klasse [c]Foo[/c] und dem Feld [c]field[/c]):
Java:
@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].
 
Zuletzt bearbeitet:
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 🙂.
 
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.
 
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 😉
 
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
Code:
null
mit einer Exception zu quittieren, da das ein eindeutiger Hinweis auf Fehlverhalten eines Systems oder Pfusch ist.
 
Ansonsten halte ich es für extrem sinnvoll übergaben von
Code:
null
mit einer Exception zu quittieren, da das ein eindeutiger Hinweis auf Fehlverhalten eines Systems oder Pfusch ist.

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.
 
Ansonsten halte ich es für extrem sinnvoll übergaben von
Code:
null
mit einer Exception zu quittieren, da das ein eindeutiger Hinweis auf Fehlverhalten eines Systems oder Pfusch ist.
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.
 
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

Code:
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();
								}
							}
						}
					}
 
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
Java:
// 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
Java:
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
Java:
-Tags und rücke ihn sinnvoll ein, damit er übersichtlicher wird.
 
Nicht zwingend. Es gibt immer wieder Situationen, in denen
Code:
null
ebenfalls ein valider Status ist. Nehmen wir String als Beispiel: Ist für dich "" (leer) das gleiche wie
Code:
null
("nicht vorhanden")? Für mich nicht.
Für mich ist das natürlich auch nicht das gleiche. Trotzdem rechtfertigt das nicht,
Code:
null
an irgendwelche Methoden zu übergeben. Die lassen sich nämlich so überladen, dass sie auch ohne Argumente funktionieren.
 

Zurück
Oben