How to Compare Strings in Java
Compare Java strings with equals, equalsIgnoreCase, compareTo, and avoid common pitfalls with ==.
Comparing two String values in Java is one of the first things a beginner gets wrong, because the == operator quietly compares references instead of contents. This chapter shows the correct, idiomatic ways to test strings for equality and ordering — equals, equalsIgnoreCase, compareTo, and the null-safe Objects.equals — and explains exactly when each one is the right tool.
For the underlying reason identical literals can be ==, see the string pool; for a broader tour of comparison techniques, see Java string comparison.
Equality of contents with equals
To check whether two strings hold the same characters, call equals:
String a = "hello";
String b = new String("hello");
boolean same = a.equals(b); // true — same charactersequals walks the two character sequences and returns true only when they have the same length and the same characters in the same order. It is the method you want 99% of the time you ask "are these two strings the same text?".
A common defensive trick is to call equals on a string literal so the receiver is never null:
if ("yes".equals(userInput)) { ... } // safe even if userInput is nullWhy == is the classic trap
== does not look at characters at all — it asks "are these the exact same object in memory?". Because the compiler interns string literals (stores one shared copy in a pool), two identical literals can happen to be ==, which lulls people into thinking == compares text. It does not: the moment a string comes from new, user input, or concatenation at runtime, == returns false even for identical text.
| Expression | Result | Why |
|---|---|---|
"java" == "java" | true | Both refer to the same interned literal |
"java" == new String("java") | false | new creates a distinct object |
"java".equals(new String("java")) | true | Compares contents, not identity |
Rule of thumb: never use == to compare strings. Reach for equals.
Case-insensitive comparison with equalsIgnoreCase
When case should not matter — usernames, file extensions, header names — use equalsIgnoreCase:
"Java".equalsIgnoreCase("JAVA"); // trueIt applies the same character-by-character logic as equals after folding case, so "README".equalsIgnoreCase("readme") is true.
Ordering with compareTo
To sort or rank strings rather than just test equality, use compareTo, which returns the sign of the lexicographic (dictionary-style) difference:
"apple".compareTo("banana"); // negative — apple comes first
"apple".compareTo("apple"); // 0 — equal
"banana".compareTo("apple"); // positive — banana comes laterA negative result means the receiver sorts before the argument, 0 means equal, positive means after. There is a compareToIgnoreCase variant, and String.CASE_INSENSITIVE_ORDER for use as a Comparator. Note that the default ordering is by Unicode code point, so all uppercase letters (A–Z) sort before all lowercase letters.
A worked example
This program exercises every approach side by side so you can see precisely how each one behaves.
What to take from the run:
a == bprintsfalseeven though both strings read "java", becausenew String("java")is a separate object — proof that==compares identity, not text.a.equals(b)printstrue:equalslooks at the characters, which is what you almost always mean by "the same string".a == cprintstrueonly because both are literals sharing one interned object — this accidental success is exactly why==lures beginners into a bug.equalsIgnoreCaseprintstruefor"Java"vs"JAVA", whilecompareToreturns0for identical text and a non-zero sign (-1for apple before banana) when they differ.Objects.equals(null, "x")printsfalseinstead of throwing, and the sorted array prints[Cherry, apple, banana]— uppercaseC(code point 67) sorts before lowercase letters (code point 97+).
Which method should I use?
Pick the comparison by the question you are actually answering:
| You want to know… | Use | Notes |
|---|---|---|
| Is the text exactly equal? | a.equals(b) | The default choice for equality |
| Equal, ignoring upper/lower case? | a.equalsIgnoreCase(b) | Folds case first |
Equal, but either side may be null? | Objects.equals(a, b) | Returns true for two nulls, never throws |
| What is their sort order? | a.compareTo(b) | Negative / 0 / positive |
| Sort order, ignoring case? | a.compareToIgnoreCase(b) | Or String.CASE_INSENSITIVE_ORDER as a Comparator |
A useful habit: when you only need equality, prefer equals (or Objects.equals when null is possible) and never compareTo(...) == 0, which does strictly more work. To explore the methods these build on, see Java string methods and the String class.