Ich habe eine ArrayList in Java, die aus einem Typ besteht, der zwei Strings und eine ganze Zahl enthält. Ich kann erfolgreich testen, ob ein Element dieser ArrayList gleich einem anderen ist, aber ich finde, dass die contains-Methode fehlschlägt. Ich glaube, das liegt an der Tatsache, dass mein Typ nicht primitiv ist.
Nun sehe ich zwei Alternativen dazu und ich frage mich, welche die beste Option ist:
Um meine eigene contains-Methode zu implementieren, indem ich durch die ArrayList iteriere und die Gleichheit jedes Elements mit dem, nach dem ich suche, überprüfe und dann die Schleife aufbringe.
Oder eine HashMap meines Typs als Schlüssel mit einer Ganzzahl als Wert anstelle der ArrayList zu verwenden. Hier kann ich mit der Methode containsKey prüfen, ob in der HashMap bereits ein Element existiert.
Der einzige Nachteil gegenüber Ansatz 2 ist, dass der Wert in meinem Fall weitgehend überflüssig ist.
Wahrscheinlich haben Sie einfach vergessen, equals()
und hashCode()
in Ihrem Typ zu überschreiben. equals()
ist das, nach dem contains()
sucht.
Aus dem Javadoc :
Gibt
true
zurück, wenn diese Liste das angegebene Element enthält. Formal ausgedrückt, wirdtrue
zurückgegeben, wenn und nur wenn diese Liste mindestens ein Elemente
enthält, so dass(o==null ? e==null : o.equals(e))
.
Seit der Standardimplementierung von equals
testet auf Referenzgleichheit, es ist nicht geeignet für benutzerdefinierte Datentypen wie dieser.
(Und wenn Sie equals
und hashCode
nicht überschrieben haben, wäre die Verwendung Ihrer Typen als Schlüssel in einem HashMap
ebenso sinnlos.)
Bearbeiten: Beachten Sie, dass Sie zum Überschreiben die exakte Signatur angeben müssen.
%Vor% Dies ist ein sehr starkes Argument für die Verwendung der @Override
Anmerkung; Das erste Beispiel wäre zur Kompilierzeit fehlgeschlagen, wenn es mit @Override
annotiert wurde.
Meine Vermutung ist, dass Sie nur eine "stark typisierte" equals-Methode geschrieben haben, anstatt gleich (Object) zu überschreiben. Mit anderen Worten, wenn Sie haben:
%Vor%brauchst du
%Vor%auch zum Überschreiben von Object.equals.
Das passt zu "equals funktioniert, aber enthält nicht, weil Ihre Tests wahrscheinlich die stark typisierten equals aufrufen, aber ArrayList nicht.
Haben Sie die equals-Methode überschrieben? Dies ist erforderlich, damit contains korrekt funktioniert.
Denken Sie daran, dass zwei Objekte Ihres Typs nur dann gleich sind, wenn sie die gleiche Instanz des Objekts sind, wenn Sie die Methode equals () nicht überschreiben. Die ArrayList-Klasse verwendet diese Methode, um zu überprüfen, ob sie das angegebene Objekt enthält. Außerdem müssen Sie die Signatur exakt anpassen, was bedeutet, dass ein Objekt als Parameter und kein Foo verwendet werden muss.
Außerdem schreibt der Objektvertrag vor, dass Sie hashCode () überschreiben müssen, wenn Sie equals () überschreiben. Wenn Sie dies nicht tun, wird eine HashMap oder HashSet Ihre zwei Objekte nicht als gleich identifizieren, selbst wenn die ArrayList dies tut (HashMap prüft auf identische Hashes und ruft dann equals () auf, um nach tatsächlicher Gleichheit zu suchen). Wenn ArrayList also sagt, dass zwei Elemente nicht gleich sind, gibt es auch keine Möglichkeit, dass HashMap dies tut. Dies bedeutet, dass Ihre zweite Lösung nicht funktioniert.
Meine Empfehlung ist zu überprüfen, dass Sie equals () und hashCode () richtig überschreiben und dass ihre Signaturen denen in der Object-Klasse entsprechen.