Explain Codes LogoExplain Codes Logo

How do I compare strings in Java?

java
string-comparison
null-safety
interning
Nikita BarsukovbyNikita Barsukov·Aug 23, 2024
TLDR

When it comes to string comparison in Java, use .equals() for exact comparisons and .equalsIgnoreCase() for ignoring case differences.

String jedi = "Obi-Wan"; String clone = "obi-wan"; boolean areSameJedi = jedi.equals(clone); // false, case-sensitive boolean moreFlexibleJedi = jedi.equalsIgnoreCase(clone); // true, case-insensitive

These are quintessential when the need to compare contents of strings, not memory addresses. Thus, they're favored over ==.

In the event of the dark side (AKA null values), Objects.equals() is your lightsaber, safe from NullPointerException.

String nullJedi = null; boolean safeJediCheck = Objects.equals(jedi, nullJedi); // false but anesthesia for NPE

Let your immutability force be strong with .equals(), the most faithful method unless you're dealing with inter-pooled or literal strings, where == can be used precisely.

May the comparison be with you

Handling null invasion

If you sense null disturbance in the force, check before using .equals() or call in Objects.equals() :

if(jedi != null && jedi.equals(clone)) { // Cheers, no nullPointerException }

Adventure through string pools

Tap into the force of String.intern() when dynamic strings must obey == for comparisons:

String internedYoda = new String("Yoda").intern(); String literalYoda = "Yoda"; boolean yodaDuplication = internedYoda == literalYoda; // true, thanks to interning

CharSequences & StringBuffers matching game

For a CharSequence or StringBuffer comparison mission, contentEquals() is your ally:

StringBuffer epicSaga = new StringBuffer("Star Wars"); boolean sagaMatch = "Star Wars".contentEquals(epicSaga); // true

Note: contentEquals() may lose its force against null battles, resulting in a NullPointerException.

Bug battling techniques

Start your comparison with non-null string literals and .equals(), and you're a bug-slaying Jedi:

if("empireStrikesBack".equals(dynamicSaga)) { // Bug-light saber active! }

Visualised journey through interning

Strings are inter-pooled or interned for better performance, literals get interned automatically:

String internedEarth = "Earth"; // Interned automatically String clonedPlanet = "Earth"; // References the interned string boolean earthTwin = internedEarth == clonedPlanet; // true: clearly not flat earth reasoning.

Immutable performance

String immutability hints at .equals() being a top preference, even if == is faster:

String samePlanet = "Mars"; String anotherMars = new String("Mars").intern(); boolean sameMars = samePlanet.equals(anotherMars); // True, aliens approves!

Zapping bugs

A misunderstood teenager (🐛) often arises when == is used:

String earthBug = new String("Bug"); String marsBug = "Bug"; boolean bugIdentityCrisis = earthBug == marsBug; // False, because Mars Bug isn't Earth Bug

To fix this bug confusion, just replace == with .equals():

boolean bugIdentityResolution = earthBug.equals(marsBug); // True, bug therapist approved

Final thought: Use .equals() for precise checks, .equalsIgnoreCase() for case flexibility, == for identity — but only when dealing with interned strings or literals.