String.equals() vs equalsIgnoreCase() vs contentEquals() — Which to Use When
Fast recall
Quick revision
Core answer
Strings character-by-character, case-sensitively, returning false if o isn't a String. `equalsIgnoreCase(String s)` does the same but normalizes each character with Character.toUpperCase() then toLowerCase() (handling Turkish-I and similar locale quirks). `contentEquals(CharSequence cs)` compares a String against any CharSequence — String, StringBuilder, StringBuffer, CharBuffer — without requiring a conversion. Rule of thumb: use equals for string-to-string, equalsIgnoreCase when case shouldn't matter, contentEquals when one side is a StringBuilder or other CharSequence. For locale-aware comparison (German ß, Turkish dotted I), use Collator instead — none of these three handle locale-specific equivalence.Whether the candidate knows the three methods have distinct purposes and when to use each, plus the locale-sensitivity gotcha
Using `==` instead of `equals`. Calling `sb.toString().equals("x")` instead of `"x".contentEquals(sb)`. Not knowing equalsIgnoreCase does BOTH upper then lower case conversion
Mention the Turkish-I problem (`equalsIgnoreCase` uses locale-insensitive comparison; for locale-aware, use `Collator`). Know that `contentEquals` avoids the allocation cost of `sb.toString()`
Interview-ready guide
Interview answer
They all compare string content — the differences are what argument types they accept and whether they're case-sensitive.
`equals(Object)`
- The default comparison; case-sensitive, character-by-character
- Returns
falseif the argument isn't aString - This is what you use 90% of the time
- Starts with an identity check so interned-string comparison is fast without needing
==
`equalsIgnoreCase(String)`
- Same as
equalsbut ignores ASCII case - Compares each character pair by applying both
toUpperCaseandtoLowerCase— handles most Unicode cases - Locale-insensitive — the Turkish dotted-I doesn't round-trip correctly
- Fine for ASCII-only data; use
Collatorfor truly locale-aware comparison
`contentEquals(CharSequence)`
- Compares against any
CharSequence:String,StringBuilder,StringBuffer,CharBuffer - Saves allocation cost vs
sb.toString().equals(...)— no intermediate String object - Useful when comparing against a growing buffer in a loop
What NOT to use
==for string content — it's reference identity; works for interned literals but breaks for runtime-built strings. Every code review flags this
For locale-aware comparison
- Use
java.text.Collator— handles German ß vs ss, Turkish dotted/dotless I, and other locale-specific equivalences thatequalsIgnoreCasecan't
Recommendation: Default to equals for string-to-string comparison. Reach for equalsIgnoreCase when case shouldn't matter (username lookups, HTTP header names, file extensions), contentEquals when one side is a StringBuilder and you want to skip the toString() allocation, and Collator when you genuinely need locale-aware equality.
`String.equals()` vs `equalsIgnoreCase()` vs `contentEquals()` — Which to Use When
Direct Answer
equals(Object o) compares two Strings character-by-character, case-sensitively, returning false if o isn't a String. equalsIgnoreCase(String s) does the same but normalizes each character with Character.toUpperCase() then toLowerCase() (handling Turkish-I and similar locale quirks). contentEquals(CharSequence cs) compares a String against any CharSequence — String, StringBuilder, StringBuffer, CharBuffer — without requiring a conversion. Rule of thumb: use equals for string-to-string, equalsIgnoreCase when case shouldn't matter, contentEquals when one side is a StringBuilder or other CharSequence. For locale-aware comparison (German ß, Turkish dotted I), use Collator instead — none of these three handle locale-specific equivalence.
Common Mistakes & Pitfalls
Using == instead of equals. Calling sb.toString().equals("x") instead of "x".contentEquals(sb). Not knowing equalsIgnoreCase does BOTH upper then lower case conversion
Check your understanding
Answer these without looking back at the article.
- Why is `"hello" == "hello"` sometimes true and sometimes false? What determines it?
- How does `equalsIgnoreCase` handle the Turkish dotted-I problem, and when would it matter?
- Why does `"abc".equals(new StringBuilder("abc"))` return false, but `contentEquals` returns true?
- What's the performance difference between `equals` and `contentEquals` for two strings?
- When would you use `java.text.Collator` over `equalsIgnoreCase`?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.