How to Compare Strings in Java (== vs equals)

Use a.equals(b) to compare String content in Java. Never use == for string comparison β€” it checks object references (addresses in memory), not character content, and produces surprising false results.

Why == fails for strings

String a = new String("hello");
String b = new String("hello");

System.out.println(a == b);      // false β€” different objects
System.out.println(a.equals(b)); // true  β€” same content

== compares the memory addresses stored in the variables, not the characters. Two new String("hello") calls allocate two separate objects, so == returns false even though the text is identical.

equals β€” content comparison

String name = "Ada";
System.out.println(name.equals("Ada"));   // true
System.out.println(name.equals("ada"));   // false (case-sensitive)

equalsIgnoreCase β€” case-insensitive comparison

String input = "YES";
if (input.equalsIgnoreCase("yes")) {
    System.out.println("Confirmed");
}

Calling equals safely (avoiding NullPointerException)

String s = null;
// s.equals("hello") β€” NullPointerException!

// Safe: call equals on the known non-null string:
"hello".equals(s);   // false, no NPE

// Or use Objects.equals:
import java.util.Objects;
Objects.equals(s, "hello");  // null-safe, returns false

compareTo β€” ordering

String s1 = "apple";
String s2 = "banana";

int result = s1.compareTo(s2);
// result < 0: s1 comes before s2 alphabetically
// result == 0: identical content
// result > 0: s1 comes after s2

Use compareToIgnoreCase for case-insensitive ordering.

contains, startsWith, endsWith

String email = "user@example.com";
email.contains("@");          // true
email.startsWith("user");     // true
email.endsWith(".com");       // true
email.matches(".*@.*\\..*"); // true (regex)

String pool and == (the nuance)

String literals defined directly in source code (String s = "hello") are interned β€” the JVM reuses the same object for identical literals. So "hello" == "hello" is true in practice, but relying on this is a bug: strings from user input, files, or new String(...) are not interned. Always use equals.