Ich habe bisher den ==
Operator in meinem Programm verwendet, um alle meine Zeichenfolgen zu vergleichen. Ich bin jedoch auf einen Fehler gestoßen, habe .equals()
stattdessen einen geändert und den Fehler behoben.
Ist ==
schlecht? Wann sollte es und sollte es nicht verwendet werden? Was ist der Unterschied?
==
dies bei Objekten so funktioniert: stackoverflow.com/a/19966154/2284641==
funktioniert manchmal, da Java über einen String-Pool verfügt, in dem versucht wird, Speicherreferenzen häufig verwendeter Strings wiederzuverwenden. Aber==
vergleicht, dass Objekte gleich sind, nicht die Werte ... so.equals()
ist die richtige Verwendung, die Sie verwenden möchten."12"=="1"+2
ist falsch (wahrscheinlich)Antworten:
==
Tests auf Referenzgleichheit (ob es sich um dasselbe Objekt handelt)..equals()
prüft auf Wertgleichheit (ob sie logisch "gleich" sind).Objects.equals () prüft
null
vor dem Aufruf.equals()
, ob dies nicht erforderlich ist (verfügbar ab JDK7, auch in Guava verfügbar ).Wenn Sie also testen möchten, ob zwei Zeichenfolgen denselben Wert haben, möchten Sie wahrscheinlich verwenden
Objects.equals()
.Sie möchten fast immer verwenden
Objects.equals()
. In der seltenen Situation, in der Sie wissen, dass Sie mit internierten Zeichenfolgen zu tun haben , können Sie diese verwenden==
.Ab JLS 3.10.5. String Literals :
Ähnliche Beispiele finden Sie auch in JLS 3.10.5-1 .
Andere zu berücksichtigende Methoden
String.equalsIgnoreCase () -Wertgleichheit , bei der Groß- und Kleinschreibung ignoriert wird.
String.contentEquals () vergleicht den Inhalt von
String
mit dem Inhalt von anyCharSequence
(verfügbar seit Java 1.5). Spart Ihnen, dass Sie Ihren StringBuffer usw. vor dem Gleichheitsvergleich in einen String umwandeln müssen, überlässt Ihnen jedoch die Nullprüfung.quelle
==
der Wert einer Variablen überprüft . Wenn Sie ein Objekt haben, hat die Variable, die auf das Objekt verweist, die Objektreferenz als Wert . Daher vergleichen Sie die Referenzen, wenn Sie zwei Variablen mit vergleichen==
. Beim Vergleich eines primitiven Datentyps wieint
ist dies immer noch der gleiche Fall. Eine Variable vom Typint
hat die Ganzzahl als Wert. So vergleichen Sie die Werte von zweiint
s mit==
. Ob dasint
der Wert einer Variablen oder einer magischen Zahl ist, spielt keine Rolle. Zusätzlich: Eine Referenz ist nichts anderes als eine Zahl, die sich auf den Speicher bezieht.==
Testet Objektreferenzen,.equals()
testet die Zeichenfolgenwerte.Manchmal sieht es so aus, als würde man
==
Werte vergleichen, weil Java einige Dinge hinter den Kulissen tut, um sicherzustellen, dass identische Inline-Zeichenfolgen tatsächlich dasselbe Objekt sind.Zum Beispiel:
Aber Vorsicht vor Nullen!
==
behandeltnull
Zeichenfolgen gut, aber das Aufrufen.equals()
von einer Nullzeichenfolge führt zu einer Ausnahme:Wenn Sie also wissen, dass dies
fooString1
möglicherweise null ist, teilen Sie dies dem Leser schriftlich mitDie folgenden sind kürzer, aber es ist weniger offensichtlich, dass nach Null gesucht wird:
quelle
==
Sie immer Werte! (Es ist nur so, dass bestimmte Werte Referenzen sind!)?.
. Das würde sichnullString1?.equals(nullString2);
in eine völlig null Aussage umwandeln . Es hilft jedoch nicht, wenn Sie habenvalidString?.equals(nullString);
- das löst immer noch eine Ausnahme aus.==
vergleicht Objektreferenzen..equals()
vergleicht String-Werte.Manchmal
==
gibt es Illusionen, String-Werte zu vergleichen, wie in folgenden Fällen:Dies liegt daran, dass die JVM beim Erstellen eines String-Literals zuerst im String-Pool nach diesem Literal sucht. Wenn eine Übereinstimmung gefunden wird, wird derselbe Verweis auf den neuen String gegeben. Aus diesem Grund erhalten wir:
(a == b) ===> wahr
Allerdings
==
scheitert im folgenden Fall:In diesem Fall wird für
new String("test")
die Anweisung eine neue Zeichenfolge auf dem Heap erstellt, und diese Referenz wird angegebenb
, sodassb
eine Referenz auf dem Heap und nicht im Zeichenfolgenpool angegeben wird.Zeigt jetzt
a
auf einen String im String-Pool, währendb
auf einen String im Heap gezeigt wird. Aus diesem Grund erhalten wir:if (a == b) ===> false.
Während
.equals()
immer ein Wert von String verglichen wird, gibt es in beiden Fällen wahr:Verwenden
.equals()
ist also immer besser.quelle
.equals()
vergleicht die Instanzen (Referenzen / Adresse), in denen als String Klassenmethoden.equals()
überschrieben werden, um Inhalte (Zeichen) zu vergleichenString
Objekte zu "zwischenspeichern" , um Speicherplatz zu sparen, der alsString
unveränderlich bekannt ist (ich hoffe, ich sage es hier richtig). Überprüfen Sie auch stackoverflow.com/questions/3052442/…Der
==
Operator prüft, ob die beiden Zeichenfolgen genau dasselbe Objekt sind.Die
.equals()
Methode prüft, ob die beiden Zeichenfolgen denselben Wert haben.quelle
Zeichenfolgen in Java sind unveränderlich. Das heißt, wenn Sie versuchen, die Zeichenfolge zu ändern, erhalten Sie eine neue Instanz. Sie können die ursprüngliche Zeichenfolge nicht ändern. Dies wurde durchgeführt, damit diese Zeichenfolgeninstanzen zwischengespeichert werden können. Ein typisches Programm enthält viele Zeichenfolgenreferenzen, und das Zwischenspeichern dieser Instanzen kann den Speicherbedarf verringern und die Leistung des Programms erhöhen.
Wenn Sie den Operator == für den Zeichenfolgenvergleich verwenden, vergleichen Sie nicht den Inhalt der Zeichenfolge, sondern die Speicheradresse. Wenn beide gleich sind, wird andernfalls true und false zurückgegeben. Während gleich in Zeichenfolge den Zeichenfolgeninhalt vergleicht.
Die Frage ist also, ob alle Zeichenfolgen im System zwischengespeichert sind. Wie kommt es, dass
==
false zurückgegeben wird, während equals true zurückgibt? Nun, das ist möglich. Wenn Sie eine neue ZeichenfolgeString str = new String("Testing")
erstellen, wie Sie sie am Ende erstellen, erstellen Sie eine neue Zeichenfolge im Cache, auch wenn der Cache bereits eine Zeichenfolge mit demselben Inhalt enthält. Kurz gesagt,"MyString" == new String("MyString")
wird immer false zurückgeben.Java spricht auch über die Funktion intern (), die für eine Zeichenfolge verwendet werden kann, um sie in den Cache aufzunehmen, sodass
"MyString" == new String("MyString").intern()
true zurückgegeben wird.Hinweis: Der Operator == ist viel schneller als gleich, nur weil Sie zwei Speicheradressen vergleichen. Sie müssen jedoch sicherstellen, dass der Code keine neuen String-Instanzen im Code erstellt. Andernfalls treten Fehler auf.
quelle
Stellen Sie sicher, dass Sie verstehen, warum. Dies liegt daran, dass der
==
Vergleich nur Referenzen vergleicht. Dieequals()
Methode führt einen zeichenweisen Vergleich des Inhalts durch.Wenn Sie new for
a
und aufrufenb
, erhält jeder eine neue Referenz, die auf die"foo"
in der Zeichenfolgentabelle verweist . Die Referenzen sind unterschiedlich, aber der Inhalt ist der gleiche.quelle
Ja, es ist schlecht ...
==
bedeutet, dass Ihre beiden Zeichenfolgenreferenzen genau dasselbe Objekt sind. Sie haben vielleicht gehört, dass dies der Fall ist, weil Java eine Art Literaltabelle führt (was es auch tut), aber das ist nicht immer der Fall. Einige Zeichenfolgen werden auf unterschiedliche Weise geladen, aus anderen Zeichenfolgen usw. aufgebaut. Sie dürfen daher niemals davon ausgehen, dass zwei identische Zeichenfolgen am selben Speicherort gespeichert sind.Gleich macht der echte Vergleich für Sie.
quelle
Ja,
==
ist schlecht für den Vergleich von Strings (alle Objekte wirklich, es sei denn, Sie wissen, dass sie kanonisch sind).==
vergleicht nur Objektreferenzen..equals()
Tests auf Gleichheit. Für Strings sind sie oft gleich, aber wie Sie festgestellt haben, ist dies nicht immer garantiert.quelle
Java verfügt über einen String-Pool, unter dem Java die Speicherzuordnung für die String-Objekte verwaltet. Siehe String-Pools in Java
Wenn Sie zwei Objekte mit dem
==
Operator überprüfen (vergleichen), wird die Adressgleichheit mit dem Zeichenfolgenpool verglichen. Wenn die beiden String-Objekte dieselben Adressreferenzen habentrue
, wird andernfalls zurückgegebenfalse
. Wenn Sie jedoch den Inhalt von zwei String-Objekten vergleichen möchten, müssen Sie dieequals
Methode überschreiben .equals
ist eigentlich die Methode der Object-Klasse, wird jedoch in die String-Klasse überschrieben und es wird eine neue Definition angegeben, die den Inhalt des Objekts vergleicht.Aber denken Sie daran, es respektiert den Fall von String. Wenn Sie zwischen Groß- und Kleinschreibung unterscheiden möchten, müssen Sie die Methode equalsIgnoreCase der String-Klasse verwenden.
Wir werden sehen:
quelle
equalsIgnoreCase
was für die frischeren informativ sein könnte.Ich stimme der Antwort von zacherates zu.
Sie können jedoch
intern()
Ihre nicht wörtlichen Zeichenfolgen aufrufen .Aus zacherates Beispiel:
Wenn Sie intern sind, lautet die nicht wörtliche String-Gleichheit
true
:quelle
==
für den Zeichenfolgenvergleich ergeben.==
vergleicht Objektreferenzen in Java , und das ist keine Ausnahme fürString
Objekte.Zum Vergleichen des tatsächlichen Inhalts von Objekten (einschließlich
String
) muss dieequals
Methode verwendet werden .Wenn sich herausstellt , dass ein Vergleich zweier
String
Objekte mit verwendet==
wird, liegt dies darantrue
, dass dieString
Objekte interniert wurden und die Java Virtual Machine über mehrere Verweise auf dieselbe Instanz von verfügtString
. Man sollte nicht das Vergleichen ein erwartetString
Objekt den gleichen Inhalt wie ein anderes enthältString
Objekt mit==
bewerten , wietrue
.quelle
.equals()
vergleicht die Daten in einer Klasse (vorausgesetzt, die Funktion ist implementiert).==
vergleicht Zeigerpositionen (Position des Objekts im Speicher).==
Gibt true zurück, wenn beide Objekte (NICHT ÜBER PRIMITIVE SPRECHEN) auf die gleiche Objektinstanz verweisen..equals()
Gibt true zurück, wenn die beiden Objekte dieselben Datenequals()
Versus==
in Java enthaltenDas kann dir helfen.
quelle
==
führt eine Referenzgleichheitsprüfung durch, ob sich die beiden Objekte (in diesem Fall Zeichenfolgen) auf dasselbe Objekt im Speicher beziehen.Die
equals()
Methode prüft, ob der Inhalt oder der Zustand von 2 Objekten identisch ist.Offensichtlich
==
ist es schneller, führt aber (möglicherweise) in vielen Fällen zu falschen Ergebnissen, wenn Sie nur feststellen möchten, ob 2String
s denselben Text enthalten.Auf jeden Fall wird die Verwendung der
equals()
Methode empfohlen.Mach dir keine Sorgen über die Leistung. Einige Dinge, die Sie zur Verwendung ermutigen sollten
String.equals()
:String.equals()
ersten Überprüfungen auf Referenzgleichheit (unter Verwendung==
), und wenn die 2 Zeichenfolgen durch Referenz gleich sind, wird keine weitere Berechnung durchgeführt!String.equals()
wird als Nächstes die Länge der Zeichenfolgen überprüft. Dies ist auch eine schnelle Operation, da dieString
Klasse die Länge der Zeichenfolge speichert und die Zeichen oder Codepunkte nicht gezählt werden müssen. Wenn sich die Längen unterscheiden, wird keine weitere Überprüfung durchgeführt. Wir wissen, dass sie nicht gleich sein können.Wenn alles gesagt und getan ist, selbst wenn wir die Garantie haben, dass die Zeichenfolgen Praktikanten sind, ist die Verwendung der
equals()
Methode immer noch nicht der Aufwand, den man denken könnte, definitiv der empfohlene Weg. Wenn Sie eine effiziente Referenzprüfung wünschen, verwenden Sie Aufzählungen, bei denen durch die Sprachspezifikation und -implementierung garantiert wird, dass derselbe Aufzählungswert dasselbe Objekt ist (als Referenz).quelle
Obviously == is faster
- Eigentlich die Durchführung der.equals(String)
ersten Überprüfungen==
vor allem anderen, also würde ich sagen, dass die Geschwindigkeit ungefähr identisch ist.public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
Wenn Sie wie ich sind, als ich anfing, Java zu verwenden, wollte ich den Operator "==" verwenden, um zu testen, ob zwei String-Instanzen gleich sind, aber zum Guten oder Schlechten ist dies in Java nicht der richtige Weg.
In diesem Tutorial werde ich verschiedene Möglichkeiten zum korrekten Vergleichen von Java-Zeichenfolgen demonstrieren, beginnend mit dem Ansatz, den ich die meiste Zeit verwende. Am Ende dieses Lernprogramms zum Vergleichen von Java-Zeichenfolgen werde ich auch erläutern, warum der Operator "==" beim Vergleichen von Java-Zeichenfolgen nicht funktioniert.
Option 1: Java-String-Vergleich mit der Equals-Methode Die meiste Zeit (möglicherweise 95% der Zeit) vergleiche ich Strings mit der Equals-Methode der Java-String-Klasse wie folgt:
Diese String equals-Methode untersucht die beiden Java-Zeichenfolgen. Wenn sie genau dieselbe Zeichenfolge enthalten, werden sie als gleich angesehen.
Wenn Sie sich ein kurzes Beispiel für einen Zeichenfolgenvergleich mit der Methode equals ansehen, werden die beiden Zeichenfolgen bei Ausführung des folgenden Tests nicht als gleich angesehen, da die Zeichen nicht exakt gleich sind (der Fall der Zeichen ist unterschiedlich):
Wenn die beiden Zeichenfolgen jedoch genau dieselbe Zeichenfolge enthalten, gibt die equals-Methode true zurück, wie in diesem Beispiel:
Option 2: Zeichenfolgenvergleich mit der equalsIgnoreCase-Methode
In einigen Zeichenfolgenvergleichstests sollten Sie ignorieren, ob die Zeichenfolgen in Groß- oder Kleinbuchstaben geschrieben sind. Wenn Sie Ihre Zeichenfolgen auf diese Weise ohne Berücksichtigung der Groß- und Kleinschreibung auf Gleichheit testen möchten, verwenden Sie die equalsIgnoreCase-Methode der String-Klasse wie folgt:
Option 3: Java-String-Vergleich mit der compareTo-Methode
Es gibt auch eine dritte, weniger verbreitete Methode zum Vergleichen von Java-Zeichenfolgen, und zwar mit der Methode compareTo der String-Klasse. Wenn die beiden Zeichenfolgen genau gleich sind, gibt die compareTo-Methode den Wert 0 (Null) zurück. Hier ist ein kurzes Beispiel dafür, wie dieser String-Vergleichsansatz aussieht:
Während ich über dieses Konzept der Gleichheit in Java schreibe, ist es wichtig zu beachten, dass die Java-Sprache eine Methode equals in der Basisklasse Java Object enthält. Wenn Sie Ihre eigenen Objekte erstellen und ein Mittel bereitstellen möchten, um festzustellen, ob zwei Instanzen Ihres Objekts "gleich" sind, sollten Sie diese Methode equals in Ihrer Klasse überschreiben (und implementieren) (auf die gleiche Weise, wie es die Java-Sprache bietet Dieses Gleichheits- / Vergleichsverhalten in der String-Gleichheitsmethode).
Vielleicht möchten Sie sich dies ansehen ==, .equals (), compareTo () und compare ()
quelle
Funktion:
Prüfung:
quelle
==
undequals
wurde bereits von anderen Lösungen beantwortet. Ich habe nur eine andere Möglichkeit angeboten, Zeichenfolgen auf lose Weise zu vergleichenDer
==
Bediener prüft, ob die beiden Referenzen auf dasselbe Objekt verweisen oder nicht..equals()
Überprüfen Sie den tatsächlichen Inhalt der Zeichenfolge (Wert).Beachten Sie, dass die
.equals()
Methode zur Klasse gehörtObject
(Superklasse aller Klassen). Sie müssen es gemäß Ihrer Klassenanforderung überschreiben, aber für String ist es bereits implementiert und es wird geprüft, ob zwei Strings denselben Wert haben oder nicht.Fall 1
Grund: Ohne Null erstellte String-Literale werden im String-Pool im Permgen-Bereich des Heaps gespeichert. Also zeigen sowohl s1 als auch s2 auf dasselbe Objekt im Pool.
Fall 2
Grund: Wenn Sie ein String-Objekt mit dem
new
Schlüsselwort erstellen , wird ihm auf dem Heap ein separater Speicherplatz zugewiesen.quelle
==
vergleicht den Referenzwert von Objekten, während dieequals()
in derjava.lang.String
Klasse vorhandene Methode den Inhalt desString
Objekts (mit einem anderen Objekt) vergleicht.quelle
equals()
Methode fürString
ist tatsächlich in derString
Klasse, nicht inObject
. Die Standardeinstellungequals()
inObject
würde nicht vergleichen, dass der Inhalt identisch ist, und gibt tatsächlich nur true zurück, wenn die Referenz identisch ist.Ich denke, wenn Sie ein
String
definieren, definieren Sie ein Objekt. Also musst du verwenden.equals()
. Wenn Sie primitive Datentypen verwenden, die Sie verwenden,==
aber mitString
(und jedem Objekt) müssen Sie verwenden.equals()
.quelle
Wenn die
equals()
Methode in derjava.lang.Object
Klasse vorhanden ist und erwartet wird, dass die Äquivalenz des Status von Objekten überprüft wird! Das heißt, der Inhalt der Objekte. Während vom==
Bediener erwartet wird, dass er überprüft, ob die tatsächlichen Objektinstanzen gleich sind oder nicht.Beispiel
Betrachten Sie zwei verschiedene Referenzvariablen
str1
undstr2
:Wenn Sie die verwenden
equals()
Sie erhalten die Ausgabe so, als
TRUE
ob Sie verwenden==
.Jetzt erhalten Sie die
FALSE
Ausgabe als, da beidestr1
undstr2
auf zwei verschiedene Objekte zeigen, obwohl beide denselben Zeichenfolgeninhalt verwenden. Es liegt daran, dassnew String()
jedes Mal ein neues Objekt erstellt wird.quelle
Operator == ist immer für den Objektreferenzvergleich gedacht , während die String-Klasse .equals () für den Inhaltsvergleich überschrieben wird :
quelle
Es wird garantiert, dass alle Objekte eine
.equals()
Methode haben, da Object eine Methode enthält.equals()
, die einen Booleschen Wert zurückgibt. Es ist Aufgabe der Unterklasse, diese Methode zu überschreiben, wenn eine weitere definierende Definition erforderlich ist. Ohne sie (dh unter Verwendung==
) werden nur Speicheradressen zwischen zwei Objekten auf Gleichheit überprüft. String überschreibt dies.equals()
Methode und gibt anstelle der Speicheradresse den Vergleich von Strings auf Zeichenebene für Gleichheit zurück.Eine wichtige Anmerkung ist, dass Zeichenfolgen in einem Klumpenpool gespeichert werden. Sobald eine Zeichenfolge erstellt wurde, wird sie für immer in einem Programm unter derselben Adresse gespeichert. Saiten ändern sich nicht, sie sind unveränderlich. Aus diesem Grund ist es eine schlechte Idee, die reguläre Zeichenfolgenverkettung zu verwenden, wenn Sie viel Zeit für die Verarbeitung von Zeichenfolgen haben. Stattdessen würden Sie die
StringBuilder
bereitgestellten Klassen verwenden. Denken Sie daran, dass sich die Zeiger auf diese Zeichenfolge ändern können. Wenn Sie interessiert sind, ob zwei Zeiger gleich sind==
, ist dies ein guter Weg. Saiten selbst nicht.quelle
final String
Variablen) und Zeichenfolgen, die Ihr Programm explizit interniert, werden in einem sogenannten "Lump Pool" gespeichert. Alle anderenString
Objekte unterliegen der Speicherbereinigung, sobald keine Live-Verweise mehr auf sie vorhanden sind, genau wie bei jedem anderen Objekttyp. Auch wenn Unveränderlichkeit erforderlich ist, damit der gesamte Internierungsmechanismus funktioniert, ist dies ansonsten irrelevant.Sie können auch die verwenden
compareTo()
Methode , um zwei Zeichenfolgen zu vergleichen. Wenn das Ergebnis compareTo 0 ist, sind die beiden Zeichenfolgen gleich, andernfalls sind die verglichenen Zeichenfolgen nicht gleich.Das
==
vergleicht die Referenzen und vergleicht nicht die tatsächlichen Zeichenfolgen. Wenn Sie jede Zeichenfolge mit erstellt habennew String(somestring).intern()
, können Sie mit dem==
Operator zwei Zeichenfolgen vergleichen. Andernfalls können nur die Methoden equals () oder compareTo verwendet werden.quelle
In Java, wenn das "==" Operator zum Vergleichen von 2 Objekten verwendet wird, wird überprüft, ob sich die Objekte auf dieselbe Stelle im Speicher beziehen. Mit anderen Worten, es wird geprüft, ob die beiden Objektnamen im Wesentlichen auf denselben Speicherort verweisen.
Die Java-String-Klasse überschreibt tatsächlich die Standardimplementierung equals () in der Object-Klasse - und überschreibt die Methode, sodass nur die Werte der Strings überprüft werden, nicht ihre Speicherorte im Speicher. Dies bedeutet, dass, wenn Sie die Methode equals () aufrufen, um 2 String-Objekte zu vergleichen, beide Objekte als gleich angesehen werden, solange die tatsächliche Zeichenfolge gleich ist.
quelle