Beim Testen auf Gleichheit String
in Java habe ich immer verwendet, equals()
weil dies für mich die natürlichste Methode dafür zu sein scheint. Immerhin sagt der Name schon, was er tun soll. Ein Kollege von mir sagte mir jedoch kürzlich, man habe mir beigebracht, compareTo() == 0
statt zu benutzen equals()
. Dies fühlt sich für mich unnatürlich an (da compareTo()
dies eine Ordnung bieten und nicht für Gleichheit vergleichen soll) und sogar etwas gefährlich (weil compareTo() == 0
dies nicht unbedingt in allen Fällen Gleichheit impliziert, obwohl ich weiß, dass dies für String
mich der Fall ist ).
Er wusste nicht, warum ihm beigebracht wurde, compareTo()
statt equals()
für zu verwenden String
, und ich konnte auch keinen Grund finden, warum. Ist das wirklich eine Frage des persönlichen Geschmacks oder gibt es einen wirklichen Grund für eine der beiden Methoden?
.equalsIgnoreCase()
der schnellste Vergleich, wenn dies angemessen ist, andernfalls.equals()
ist es das, was Sie wollen.compareTo() == 0
Bedeutet nicht unbedingt in allen Fällen Gleichheit". Das ist absolut richtig! Dies ist genau das, was der Ausdruck "konsistent mit Gleichen" in den Java-API-Spezifikationen bedeutet, beispielsweise in der Vergleichsspezifikation . Zum Beispiel ist String der Vergleichsmethode mit equals konsistent, aber BigDecimal der Vergleichsmethode ist inkonsistent mit equals.Antworten:
Ein Unterschied besteht darin, dass
"foo".equals((String)null)
false zurückgegeben wird, während"foo".compareTo((String)null) == 0
eine NullPointerException ausgelöst wird. Sie sind also auch für Strings nicht immer austauschbar.quelle
Die 2 Hauptunterschiede sind:
equals
nimmt jedes Objekt als Parameter, abercompareTo
nur Strings.equals
sagt Ihnen nur, ob sie gleich sind oder nicht,compareTo
gibt aber Auskunft darüber, wie die Strings lexikographisch verglichen werden.Ich habe mir den String-Klassencode angesehen , und der Algorithmus in compareTo und equals sieht im Grunde gleich aus. Ich glaube, seine Meinung war nur eine Frage des Geschmacks, und ich stimme Ihnen zu - wenn Sie nur die Gleichheit der Saiten wissen müssen und nicht, welche lexikographisch zuerst kommt, dann würde ich sie verwenden
equals
.quelle
Wenn Sie für Gleichheit vergleichen, sollten Sie verwenden
equals()
, weil es Ihre Absicht in klarer Weise ausdrückt.compareTo()
hat den zusätzlichen Nachteil, dass es nur bei Objekten funktioniert, die das implementierenComparable
Schnittstelle .Dies gilt im Allgemeinen nicht nur für Strings.
quelle
compareTo
hat mehr Arbeit gemacht, wenn die Saiten unterschiedlich lang sind.equals
kann einfach false zurückgeben,compareTo
muss aber immer genügend Zeichen untersuchen, um die Sortierreihenfolge zu finden.quelle
compareTo()
Dies gilt nicht nur für Strings, sondern auch für jedes andere Objekt, dacompareTo<T>
ein generisches Argument verwendet wirdT
. String ist eine der Klassen, die diecompareTo()
Methode durch Implementierung derComparable
Schnittstelle implementiert haben. (compareTo () ist eine Methode für die vergleichbare Schnittstelle). Es steht also jeder Klasse frei, die Schnittstelle Comparable zu implementieren.Aber
compareTo()
gibt die Reihenfolge der Objekte , typischerweise verwendet in Objekte in aufsteigender Sortierung oder absteigender Reihenfolge , währendequals()
nur über die Gleichheit reden und sagen , ob sie gleich sind oder nicht.quelle
Im
Zeichenfolgenkontext: compareTo: Vergleicht zwei Zeichenfolgen lexikografisch.
gleich: Vergleicht diese Zeichenfolge mit dem angegebenen Objekt.
compareTo vergleicht zwei Zeichenfolgen anhand ihrer Zeichen (am selben Index) und gibt entsprechend eine Ganzzahl (positiv oder negativ) zurück.
quelle
Ein sehr wichtiger Unterschied zwischen compareTo und equals:
equals () prüft, ob zwei Objekte gleich sind oder nicht und gibt einen Booleschen Wert zurück.
compareTo () (von der Schnittstelle Comparable ) gibt eine Ganzzahl zurück. Es wird geprüft, welches der beiden Objekte "kleiner als", "gleich" oder "größer als" das andere ist. Nicht alle Objekte können logisch geordnet werden, daher ist eine compareTo () -Methode nicht immer sinnvoll.
Beachten Sie, dass equals () nicht die Reihenfolge zwischen Objekten definiert, wie es compareTo () tut.
Jetzt rate ich Ihnen, den Quellcode beider Methoden zu überprüfen, um zu dem Schluss zu kommen, dass Gleichheit gegenüber compareTo vorzuziehen ist, das einige mathematische Berechnungen umfasst.
quelle
Es scheint, dass beide Methoden so ziemlich dasselbe tun, aber die compareTo () -Methode nimmt einen String und kein Objekt auf und fügt zusätzlich zur normalen equals () -Methode einige zusätzliche Funktionen hinzu. Wenn Sie sich nur für Gleichheit interessieren, ist die Methode equals () die beste Wahl, einfach weil sie für den nächsten Programmierer, der sich Ihren Code ansieht, sinnvoller ist. Der Zeitunterschied zwischen den beiden verschiedenen Funktionen sollte keine Rolle spielen, es sei denn, Sie durchlaufen eine große Anzahl von Elementen. Das compareTo () ist sehr nützlich, wenn Sie die Reihenfolge der Zeichenfolgen in einer Sammlung kennen müssen oder wenn Sie den Längenunterschied zwischen Zeichenfolgen kennen müssen, die mit derselben Zeichenfolge beginnen.
Quelle: http://java.sun.com/javase/6/docs/api/java/lang/String.html
quelle
equals()
sollte im Fall des OP die Methode der Wahl sein.Wenn wir uns die Implementierung von
equals()
undcompareTo()
in java.lang.String auf grepcode ansehen , können wir leicht erkennen, dass Gleichheit besser ist, wenn wir uns nur mit der Gleichheit zweier Zeichenfolgen befassen:equals()
::und
compareTo()
:Wenn eine der Zeichenfolgen ein Präfix einer anderen ist, ist die Leistung von
compareTo()
schlechter, da die lexikografische Reihenfolge noch bestimmtequals()
werden muss, ohne sich mehr Sorgen zu machen und sofort false zurückzugeben.Meiner Meinung nach sollten wir diese beiden so verwenden, wie sie beabsichtigt waren:
equals()
auf Gleichheit prüfen undcompareTo()
um die lexikalische Reihenfolge zu finden.quelle
equals () prüft, ob zwei Zeichenfolgen gleich sind oder nicht. Es gibt einen booleschen Wert. compareTo () prüft, ob das Zeichenfolgenobjekt dem anderen Zeichenfolgenobjekt entspricht, größer oder kleiner ist. Das Ergebnis lautet: 1, wenn das Zeichenfolgenobjekt größer ist 0, wenn beide gleich -1 sind, wenn die Zeichenfolge kleiner als die andere Zeichenfolge ist
Gl.:
quelle
Es gibt bestimmte Dinge, die Sie beim Überschreiben von compareTo in Java beachten müssen, z. B. muss Compareto mit equals konsistent sein und die Subtraktion sollte nicht zum Vergleichen von Ganzzahlfeldern verwendet werden, da diese überlaufen können. Weitere Informationen finden Sie unter Beachten Sie beim Überschreiben von Comparator in Java .
quelle
Dies ist ein Experiment in Nekromantie :-)
Die meisten Antworten vergleichen Leistungs- und API-Unterschiede. Sie übersehen den grundlegenden Punkt, dass die beiden Operationen einfach unterschiedliche Semantik haben.
Ihre Intuition ist richtig. x.equals (y) ist nicht austauschbar mit x.compareTo (y) == 0. Der erste vergleicht die Identität, während der andere den Begriff 'Größe' vergleicht. Es ist wahr, dass in vielen Fällen, insbesondere bei primitiven Typen, diese beiden zusammenpassen.
Der allgemeine Fall ist folgender:
Wenn x und y identisch sind, haben sie dieselbe 'Größe': Wenn x.equals (y) wahr ist => x.compareTo (y) ist 0.
Wenn jedoch x und y dieselbe Größe haben, bedeutet dies nicht, dass sie identisch sind.
Wenn x.compareTo (y) 0 ist, bedeutet dies nicht unbedingt, dass x.equals (y) wahr ist.
Ein überzeugendes Beispiel, bei dem sich Identität von Größe unterscheidet, wären komplexe Zahlen. Angenommen, der Vergleich erfolgt nach ihrem absoluten Wert. Also zwei komplexe Zahlen gegeben: Z1 = a1 + b1 * i und Z2 = a2 + b2 * i:
Z1.equals (z2) gibt genau dann true zurück, wenn a1 = a2 und b1 = b2.
Z1.compareTo (Z2) gibt jedoch 0 für und eine unendliche Anzahl von (a1, b1) und (a2, b2) Paaren zurück, solange sie die Bedingung a1 ^ 2 + b1 ^ 2 == a2 ^ 2 + b2 ^ 2 erfüllen.
quelle
Gleiche können effizienter sein als compareTo.
Wenn die Länge der Zeichenfolgen in String nicht übereinstimmt, sind die Strings auf keinen Fall gleich, sodass die Zurückweisung viel schneller erfolgen kann.
Wenn es sich um dasselbe Objekt handelt (Identitätsgleichheit statt logische Gleichheit), ist es außerdem effizienter.
Wenn sie auch das HashCode-Caching implementiert haben, könnte es noch schneller sein, Ungleichwerte abzulehnen, falls ihre HashCodes nicht übereinstimmen.
quelle
String.equals()
erfordert das Aufrufen desinstanceof
Operators, während diescompareTo()
nicht erforderlich ist. Mein Kollege hat einen großen Leistungsabfall festgestellt, der durch eine übermäßige Anzahl voninstanceof
Aufrufen in derequals()
Methode verursacht wurde. Mein Test hat sich jedoch bewährtcompareTo()
nur etwas schneller sein.Ich habe jedoch Java 1.6 verwendet. Bei anderen Versionen (oder anderen JDK-Anbietern) kann der Unterschied größer sein.
Der Test verglich jede Zeichenfolge in 1000 Elementarrays, die zehnmal wiederholt wurden.
quelle
compareTo()
es schneller ist alsequals()
? Für die meisten Datensätze in der realen Weltequals()
ist dies jedoch viel schneller alscompareTo() == 0
.equals()
leuchtet, wenn die Zeichenfolgen ein gemeinsames Präfix, aber unterschiedliche Längen haben oder wenn sie tatsächlich dasselbe Objekt sind.equals
kann jedes Objekt als Parameter nehmen, abercompareTo
nur String.Wenn cometo null,
compareTo
wird eine Ausnahme ausgelöstWenn Sie wissen möchten, wo der Unterschied auftritt, können Sie verwenden
compareTo
.quelle
equals
: Erforderlich für die Überprüfung der Gleichheit und die Einschränkung von Duplikaten. Viele Klassen der Java-Bibliothek verwenden dies, wenn sie Duplikate suchen möchten. zBHashSet.add(ob1)
wird nur hinzugefügt, wenn das nicht existiert. Wenn Sie also einige Klassen wie diese erweitern, überschreiben Sie sieequals()
.compareTo
: Erforderlich für die Bestellung des Elements. Auch hier benötigen Sie für eine stabile Sortierung Gleichheit, daher gibt es eine Rückgabe 0.quelle
Gleich -
1- Überschreiben Sie die GetHashCode-Methode, damit ein Typ in einer Hash-Tabelle ordnungsgemäß funktioniert.
2- Bei der Implementierung einer Equals-Methode keine Ausnahme auslösen. Geben Sie stattdessen false für ein Nullargument zurück.
3-
Aufeinanderfolgende Aufrufe von x.Equals (y) geben denselben Wert zurück, solange das von x und y referenzierte Objekt nicht geändert wird.
4- Für einige Arten von Objekten ist es wünschenswert, dass Equals anstelle von referentieller Gleichheit auf Wertgleichheit getestet wird. Solche Implementierungen von Equals geben true zurück, wenn die beiden Objekte denselben Wert haben, auch wenn sie nicht dieselbe Instanz sind.
Zum Beispiel -
Ausgabe :-
während compareTo -
Vergleicht die aktuelle Instanz mit einem anderen Objekt desselben Typs und gibt eine Ganzzahl zurück, die angibt, ob die aktuelle Instanz in der Sortierreihenfolge dem anderen Objekt vorausgeht, folgt oder an derselben Position auftritt.
Es kehrt zurück -
Kleiner als Null - Diese Instanz steht in der Sortierreihenfolge vor obj. Null - Diese Instanz tritt an derselben Position in der Sortierreihenfolge wie obj auf. Größer als Null - Diese Instanz folgt obj in der Sortierreihenfolge.
Es kann eine ArgumentException auslösen, wenn das Objekt nicht vom Typ der Instanz ist.
Zum Beispiel können Sie hier besuchen.
Daher empfehle ich besser, Equals anstelle von compareTo zu verwenden.
quelle
GetHashCode()
Methode. Meinst duhashCode()
?"gleich" vergleicht Objekte und gibt true oder false zurück und "compare to" gibt 0 zurück, wenn true oder eine Zahl [> 0] oder [<0], wenn dies hier falsch ist. Ein Beispiel:
Ergebnisse:
Dokumentation Vergleichen Sie mit: https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
Dokumentation gleich: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)
quelle
Hier ist eine Sache wichtig, während
compareTo()
over verwendet wirdequals()
,compareTo
die für die Klassen funktioniert, die die 'Comparable'-Schnittstelle implementieren, andernfalls wird a ausgelöstNullPointerException
.String
Klassen implementiert eine vergleichbare Schnittstelle, die SieStringBuffer
jedoch nicht"foo".compareTo("doo")
inString
Objekt, aber nicht inStringBuffer
Objekt verwenden können.quelle
Dies gibt -2 und false aus
Dies gibt 2 und false aus
Dies gibt 0 und true aus
equals gibt genau dann einen booleschen Wert zurück, wenn beide Zeichenfolgen übereinstimmen.
compareTo soll nicht nur sagen, ob sie übereinstimmen, sondern auch, welcher String kleiner als der andere ist und auch wie viel lexikographisch. Dies wird hauptsächlich beim Sortieren in der Sammlung verwendet.
quelle
Ich glaube
equals
undequalsIgnoreCase
Methoden derString
Rückgabetrue
undfalse
das ist nützlich, wenn Sie die Werte des String-Objekts vergleichen wollten, aber im Falle der ImplementierungcompareTo
undcompareToIgnoreCase
Methoden gibt positive, negative und Null-Wert, die im Fall der Sortierung nützlich sein wird.quelle