723 Stimmen

Wie kann ich in Java Zeichenketten vergleichen?

Ich habe die == Operator in meinem Programm, um alle meine bisherigen Zeichenketten zu vergleichen. Allerdings bin ich auf einen Fehler gestoßen und habe eine davon in .equals() und der Fehler wurde dadurch behoben.

Es == schlecht? Wann sollte sie verwendet werden und wann nicht? Worin besteht der Unterschied?

6109voto

Aaron Maenpaa Punkte 112919

== prüft auf Referenzgleichheit (ob es sich um dasselbe Objekt handelt).

.equals() prüft, ob die Werte gleich sind (ob sie logisch "gleich" sind).

Objects.equals() prüft auf null vor dem Aufruf .equals() damit Sie das nicht tun müssen (verfügbar ab JDK7, auch verfügbar in Guave ).

Wenn Sie also testen wollen, ob zwei Zeichenketten den gleichen Wert haben, werden Sie wahrscheinlich die Objects.equals() .

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

Du hast fast つねに verwenden wollen Objects.equals() . In der selten Situation, in der Sie wissen Sie haben es zu tun mit interniert Strings, Sie kann verwenden. == .

Desde JLS 3.10.5. String-Literale :

Außerdem bezieht sich ein String-Literal immer auf die dieselbe Instanz der Klasse String . Dies liegt daran, dass Stringliterale - oder allgemeiner gesagt, Strings, die die Werte von konstanten Ausdrücken sind ( §15.28 ) - werden "interniert", um eindeutige Instanzen gemeinsam zu nutzen, wobei die Methode String.intern .

Ähnliche Beispiele finden sich auch in JLS 3.10.5-1 .

Andere zu berücksichtigende Methoden

String.equalsIgnoreCase() Wertgleichheit, die Groß- und Kleinschreibung ignoriert. Beachten Sie jedoch, dass diese Methode in verschiedenen ortsabhängigen Fällen zu unerwarteten Ergebnissen führen kann, siehe diese Frage .

String.contentEquals() vergleicht den Inhalt der String mit dem Inhalt eines beliebigen CharSequence (verfügbar seit Java 1.5). Erspart Ihnen die Umwandlung Ihres StringBuffers usw. in einen String, bevor Sie den Gleichheitsvergleich durchführen, überlässt Ihnen aber die Nullprüfung.

787voto

Whatsit Punkte 9737

== prüft Objektreferenzen, .equals() testet die String-Werte.

Manchmal sieht es so aus, als ob == vergleicht Werte, weil Java hinter den Kulissen dafür sorgt, dass identische Inline-Strings tatsächlich dasselbe Objekt sind.

Zum Beispiel:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

Aber Vorsicht vor Nullen!

== Griffe null Zeichenketten gut, aber der Aufruf .equals() aus einer Null-Zeichenkette wird eine Ausnahme verursachen:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Wenn Sie also wissen, dass fooString1 ungültig sein kann, teilen Sie dem Leser mit, dass durch das Schreiben von

System.out.print(fooString1 != null && fooString1.equals("bar"));

Die folgenden sind kürzer, aber es ist weniger offensichtlich, dass sie auf null geprüft werden:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required

481voto

Ganesh Punkte 914

== vergleicht Objektreferenzen.

.equals() vergleicht String-Werte.

Manchmal == gibt Illusionen über den Vergleich von String-Werten, wie in den folgenden Fällen:

String a="Test";
String b="Test";
if(a==b) ===> true

Wenn Sie nämlich ein String-Literal erstellen, sucht die JVM zunächst nach diesem Literal im String-Pool, und wenn sie eine Übereinstimmung findet, wird diese Referenz dem neuen String zugewiesen. Aus diesem Grund erhalten wir:

(a==b) ===> wahr

                       String Pool
     b -----------------> "test" <-----------------a

Allerdings, == schlägt im folgenden Fall fehl:

String a="test";
String b=new String("test");
if (a==b) ===> false

In diesem Fall für new String("test") wird die Anweisung new String auf dem Heap erstellt, und diese Referenz wird an b also b wird ein Verweis auf den Heap und nicht auf den String-Pool gegeben.

Jetzt a auf einen String im String-Pool verweist, während b auf einen String auf dem Heap verweist. Deshalb erhalten wir:

if(a==b) ===> false.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Während .equals() vergleicht immer einen Wert von String, so dass es in beiden Fällen wahr ergibt:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Also mit .equals() ist immer besser.

234voto

Clayton Punkte 5777

Le site == Operator prüft, ob die beiden Zeichenketten genau dasselbe Objekt sind.

Le site .equals() Methode prüft, ob die beiden Zeichenketten den gleichen Wert haben.

188voto

Faisal Feroz Punkte 11796

Strings in Java sind unveränderlich. Das bedeutet, dass Sie jedes Mal, wenn Sie versuchen, die Zeichenfolge zu ändern, eine neue Instanz erhalten. Die ursprüngliche Zeichenfolge kann nicht geändert werden. Dies wurde gemacht, damit diese String-Instanzen zwischengespeichert werden können. Ein typisches Programm enthält viele String-Referenzen und das Zwischenspeichern dieser Instanzen kann den Speicherbedarf verringern und die Leistung des Programms erhöhen.

Wenn Sie den Operator == für einen Stringvergleich verwenden, vergleichen Sie nicht den Inhalt des Strings, sondern die Speicheradresse. Wenn beide gleich sind, wird true zurückgegeben, andernfalls false. Der Operator == in String vergleicht hingegen den Inhalt der Zeichenkette.

Die Frage ist also, wenn alle Zeichenketten im System zwischengespeichert sind, wie kommt es dann, dass == false zurückgibt, während equals true zurückgibt? Nun, das ist möglich. Wenn Sie eine neue Zeichenkette erstellen wie String str = new String("Testing") wird eine neue Zeichenfolge im Cache angelegt, 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 von der Funktion intern(), die auf eine Zeichenkette angewendet werden kann, um sie in den Cache aufzunehmen. "MyString" == new String("MyString").intern() wird true zurückgegeben.

Hinweis: Der ==-Operator ist viel schneller als der Gleichheitsoperator, weil Sie zwei Speicheradressen vergleichen, aber Sie müssen sicher sein, dass der Code keine neuen String-Instanzen im Code erzeugt. Andernfalls werden Sie auf Bugs stoßen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X