Strings in Java vergleichen
Java-Strings mit equals, equalsIgnoreCase und compareTo vergleichen und typische Fehler mit == vermeiden.
Zwei String-Werte in Java zu vergleichen ist eines der ersten Dinge, die Anfänger falsch machen, weil der Operator == still und leise Referenzen statt Inhalte vergleicht. Dieses Kapitel zeigt die korrekten, idiomatischen Wege, um Strings auf Gleichheit und Reihenfolge zu prüfen — equals, equalsIgnoreCase, compareTo und das null-sichere Objects.equals — und erklärt genau, wann welches Mittel das richtige ist.
Den Hintergrund, warum identische Literale == sein können, findest du unter the string pool; eine umfassendere Übersicht der Vergleichstechniken bietet Java string comparison.
Inhaltsgleichheit mit equals
Um zu prüfen, ob zwei Strings dieselben Zeichen enthalten, rufe equals auf:
String a = "hello";
String b = new String("hello");
boolean same = a.equals(b); // true — same charactersequals durchläuft beide Zeichenfolgen und gibt true zurück, wenn sie dieselbe Länge und dieselben Zeichen in derselben Reihenfolge haben. Diese Methode willst du 99 % der Zeit, wenn du fragst „Sind diese beiden Strings derselbe Text?".
Ein gängiger defensiver Trick ist, equals auf einem String-Literal aufzurufen, damit der Empfänger niemals null ist:
if ("yes".equals(userInput)) { ... } // safe even if userInput is nullWarum == die klassische Falle ist
== schaut gar nicht erst auf die Zeichen — es fragt „Sind das genau dasselbe Objekt im Speicher?". Weil der Compiler String-Literale interniert (eine gemeinsam genutzte Kopie in einem Pool ablegt), können zwei identische Literale zufällig == sein, was Leute zu der Annahme verleitet, == vergleiche Text. Das tut es nicht: Sobald ein String aus new, Benutzereingaben oder einer Laufzeitverkettung stammt, gibt == false zurück — auch bei identischem Text.
| Ausdruck | Ergebnis | Warum |
|---|---|---|
"java" == "java" | true | Beide verweisen auf dasselbe internierte Literal |
"java" == new String("java") | false | new erzeugt ein eigenständiges Objekt |
"java".equals(new String("java")) | true | Vergleicht Inhalte, nicht Identität |
Faustregel: Verwende == niemals zum Vergleich von Strings. Greife auf equals zurück.
Groß-/Kleinschreibung ignorieren mit equalsIgnoreCase
Wenn Groß- und Kleinschreibung keine Rolle spielen soll — Benutzernamen, Dateiendungen, Header-Namen — verwende equalsIgnoreCase:
"Java".equalsIgnoreCase("JAVA"); // trueEs wendet dieselbe zeichenweise Logik wie equals an, faltet aber zuvor die Groß-/Kleinschreibung, sodass "README".equalsIgnoreCase("readme") true ergibt.
Reihenfolge mit compareTo
Um Strings zu sortieren oder zu ordnen, anstatt nur Gleichheit zu prüfen, verwende compareTo, das das Vorzeichen der lexikografischen (alphabetischen) Differenz zurückgibt:
"apple".compareTo("banana"); // negative — apple comes first
"apple".compareTo("apple"); // 0 — equal
"banana".compareTo("apple"); // positive — banana comes laterEin negatives Ergebnis bedeutet, dass der Empfänger vor dem Argument sortiert, 0 bedeutet gleich, positiv bedeutet nach. Es gibt eine compareToIgnoreCase-Variante und String.CASE_INSENSITIVE_ORDER zur Verwendung als Comparator. Beachte, dass die Standardreihenfolge nach Unicode-Codepunkt gilt, sodass alle Großbuchstaben (A–Z) vor allen Kleinbuchstaben sortieren.
Ein durchgearbeitetes Beispiel
Dieses Programm übt jeden Ansatz nebeneinander, damit du genau siehst, wie sich jeder verhält.
Was aus dem Ergebnis hervorzuheben ist:
a == bgibtfalseaus, obwohl beide Strings „java" lauten, weilnew String("java")ein separates Objekt ist — Beweis dafür, dass==Identität vergleicht, nicht Text.a.equals(b)gibttrueaus:equalsschaut auf die Zeichen, was fast immer gemeint ist, wenn man „derselbe String" sagt.a == cgibttruenur aus, weil beide Literale dasselbe internierte Objekt teilen — dieser zufällige Erfolg ist genau der Grund, warum==Anfänger in einen Bug lockt.equalsIgnoreCasegibttruefür"Java"vs."JAVA"aus, währendcompareTofür identischen Text0zurückgibt und ein von null verschiedenes Vorzeichen (-1für apple vor banana), wenn sie sich unterscheiden.Objects.equals(null, "x")gibtfalseaus, anstatt zu werfen, und das sortierte Array gibt[Cherry, apple, banana]aus — der GroßbuchstabeC(Codepunkt 67) sortiert vor Kleinbuchstaben (Codepunkt 97+).
Welche Methode soll ich verwenden?
Wähle den Vergleich nach der Frage, die du wirklich beantworten möchtest:
| Du möchtest wissen… | Verwende | Hinweise |
|---|---|---|
| Ist der Text exakt gleich? | a.equals(b) | Die Standardwahl für Gleichheit |
| Gleich, Groß-/Kleinschreibung ignoriert? | a.equalsIgnoreCase(b) | Faltet Groß-/Kleinschreibung zuerst |
Gleich, aber eine Seite kann null sein? | Objects.equals(a, b) | Gibt true für zwei nulls zurück, wirft nie |
| Was ist ihre Sortierreihenfolge? | a.compareTo(b) | Negativ / 0 / positiv |
| Sortierreihenfolge, Groß-/Kleinschreibung ignoriert? | a.compareToIgnoreCase(b) | Oder String.CASE_INSENSITIVE_ORDER als Comparator |
Eine nützliche Gewohnheit: Wenn du nur Gleichheit brauchst, bevorzuge equals (oder Objects.equals, wenn null möglich ist) und nie compareTo(...) == 0, das streng mehr Arbeit leistet. Um die Methoden zu erkunden, auf denen diese aufbauen, siehe Java string methods und die String-Klasse.