Development

Java: == vs equals() and Why Strings Trip Everyone Up

What == really compares in Java, why new String("a") differs from "a", and how to write reliable comparisons for strings and your own classes.

SmartCampus Buddy TeamSeptember 17, 20265 min read

Comparing things looks simple in Java until a program that should say "equal" says "not equal". The cause is almost always the difference between comparing references and comparing content.

What == compares

For primitive types such as int and double, == compares values. For objects, == compares references: whether both variables point to the very same object in memory.

String a = new String("java");
String b = "java";
System.out.println(a == b);       // false
System.out.println(a.equals(b));  // true

The string pool

String literals are stored in a shared pool, so two identical literals often refer to the same object and == happens to return true. Creating a string with new makes a separate object. Relying on that pooling is an accident waiting to happen, so always compare string content with equals.

Comparing safely

If a value might be null, calling variable.equals("x") throws a NullPointerException. Put the known value first: "x".equals(variable), or use Objects.equals(a, b).

Your own classes

The default equals inherited from Object also compares references. To compare by content, override equals. When you do, you must also override hashCode so that equal objects produce equal hash codes, otherwise HashMap and HashSet will behave incorrectly.

Key takeaways

  • Use == for primitives, equals for object content.
  • Do not depend on the string pool.
  • Put the non-null value first, or use Objects.equals.
  • Override equals and hashCode together.