Introduction
Equality testing in Java is the process of checking if two values or objects are equal. Java provides different ways to test equality depending on whether you’re comparing primitive types or objects.
Two Types of Equality
- Reference Equality: Comparing memory addresses (using
==) - Content Equality: Comparing actual values (using
equals())
1. Equality for Primitive Types
For primitive types (int, double, char, boolean, etc.), use == operator.
Syntax:
value1 == value2
Examples:
// Integer comparison
int a = 10;
int b = 10;
System.out.println(a == b); // true
int x = 5;
int y = 10;
System.out.println(x == y); // false
// Double comparison
double d1 = 10.5;
double d2 = 10.5;
System.out.println(d1 == d2); // true
// Character comparison
char c1 = 'A';
char c2 = 'A';
System.out.println(c1 == c2); // true
// Boolean comparison
boolean flag1 = true;
boolean flag2 = true;
System.out.println(flag1 == flag2); // true
Not Equal (!=):
int a = 10;
int b = 20;
System.out.println(a != b); // true
int x = 5;
int y = 5;
System.out.println(x != y); // false
2. Equality for Reference Types (Objects)
For objects, you need to understand the difference between == and equals().
a) Using == (Reference Comparison)
Compares memory addresses (references), not content.
String s1 = new String("Hello");
String s2 = new String("Hello");
String s3 = s1;
// == compares references
System.out.println(s1 == s2); // false (different objects)
System.out.println(s1 == s3); // true (same reference)
Visual Representation:
Heap Memory:
[Object1: "Hello"] ← s1
[Object2: "Hello"] ← s2
[Object1: "Hello"] ← s3 (same as s1)
s1 == s2: false (different memory addresses)
s1 == s3: true (same memory address)
b) Using equals() (Content Comparison)
Compares actual content of objects.
String s1 = new String("Hello");
String s2 = new String("Hello");
String s3 = new String("World");
// equals() compares content
System.out.println(s1.equals(s2)); // true (same content)
System.out.println(s1.equals(s3)); // false (different content)
String Equality (Special Case)
String Literals vs new String()
// String literals (stored in String Pool)
String s1 = "Hello";
String s2 = "Hello";
// new keyword (created in Heap)
String s3 = new String("Hello");
String s4 = new String("Hello");
System.out.println("== comparisons:");
System.out.println(s1 == s2); // true (same object in pool)
System.out.println(s3 == s4); // false (different objects in heap)
System.out.println(s1 == s3); // false (pool vs heap)
System.out.println("\nequals() comparisons:");
System.out.println(s1.equals(s2)); // true
System.out.println(s3.equals(s4)); // true
System.out.println(s1.equals(s3)); // true
// All equals() return true because content is same
Memory Diagram:
String Pool: Heap:
["Hello"] ← s1, s2
["Hello"] ← s3
["Hello"] ← s4
equals() Method Details
String equals():
String str1 = "Java";
String str2 = "Java";
String str3 = "java";
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // false (case-sensitive)
equalsIgnoreCase():
String str1 = "Java";
String str2 = "java";
String str3 = "JAVA";
System.out.println(str1.equalsIgnoreCase(str2)); // true
System.out.println(str1.equalsIgnoreCase(str3)); // true
Common Mistakes
Mistake 1: Using == for Strings
// WRONG
String input = new String("admin");
String password = "admin";
if (input == password) { // ❌ May fail
System.out.println("Login successful");
}
// CORRECT
if (input.equals(password)) { // ✓ Correct
System.out.println("Login successful");
}
Mistake 2: Null Pointer Exception
String str = null;
// Will throw NullPointerException
if (str.equals("Hello")) { // ❌ Error
// code
}
// Safe way
if ("Hello".equals(str)) { // ✓ Safe (no exception)
// code
}
// Or check null first
if (str != null && str.equals("Hello")) { // ✓ Safe
// code
}
Mistake 3: Case Sensitivity
String input = "Java";
String expected = "java";
if (input.equals(expected)) { // false
System.out.println("Match");
}
// Use equalsIgnoreCase if case doesn't matter
if (input.equalsIgnoreCase(expected)) { // true
System.out.println("Match");
}
Comparing Other Objects
Integer Wrapper Class:
Integer num1 = 100;
Integer num2 = 100;
Integer num3 = new Integer(100);
System.out.println(num1 == num2); // true (Integer cache)
System.out.println(num1 == num3); // false (different objects)
System.out.println(num1.equals(num2)); // true
System.out.println(num1.equals(num3)); // true
Note: Java caches Integer objects from -128 to 127.
Custom Objects:
class Student {
int id;
String name;
Student(int id, String name) {
this.id = id;
this.name = name;
}
// Override equals() for content comparison
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Student student = (Student) obj;
return id == student.id && name.equals(student.name);
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student(1, "John");
Student s2 = new Student(1, "John");
Student s3 = s1;
System.out.println(s1 == s2); // false (different objects)
System.out.println(s1 == s3); // true (same reference)
System.out.println(s1.equals(s2)); // true (same content, if equals() overridden)
}
}
Comparison Methods Summary
For Primitives:
int a = 10, b = 10;
boolean equal = (a == b); // true
boolean notEqual = (a != b); // false
For Strings:
String s1 = "Hello";
String s2 = "Hello";
// Reference comparison
boolean sameRef = (s1 == s2);
// Content comparison
boolean sameContent = s1.equals(s2);
// Case-insensitive
boolean sameCaseInsensitive = s1.equalsIgnoreCase(s2);
For Objects:
Object obj1 = new Object();
Object obj2 = new Object();
// Reference comparison
boolean sameRef = (obj1 == obj2);
// Content comparison (if equals() is overridden)
boolean sameContent = obj1.equals(obj2);
Best Practices
1. Use equals() for Objects:
// Good
if (str1.equals(str2)) { }
// Bad for content comparison
if (str1 == str2) { }
2. Null-Safe Comparison:
// Method 1: Literal first
if ("expected".equals(variable)) { }
// Method 2: Null check
if (variable != null && variable.equals("expected")) { }
// Method 3: Objects.equals() (Java 7+)
if (Objects.equals(str1, str2)) { } // Null-safe
3. Use equalsIgnoreCase() When Appropriate:
String input = "Admin";
if (input.equalsIgnoreCase("admin")) {
// Login successful
}
4. Override equals() in Custom Classes:
@Override
public boolean equals(Object obj) {
// Proper implementation
}
Comparison Operators
Relational Operators:
int a = 10, b = 20;
boolean equal = (a == b); // false
boolean notEqual = (a != b); // true
boolean greater = (a > b); // false
boolean less = (a < b); // true
boolean greaterOrEqual = (a >= b); // false
boolean lessOrEqual = (a <= b); // true
Objects.equals() (Java 7+)
Null-safe equality check:
import java.util.Objects;
String s1 = "Hello";
String s2 = "Hello";
String s3 = null;
// Safe - handles null
System.out.println(Objects.equals(s1, s2)); // true
System.out.println(Objects.equals(s1, s3)); // false
System.out.println(Objects.equals(s3, s3)); // true (both null)
// Traditional way would throw NullPointerException
// System.out.println(s3.equals(s1)); // ❌ NullPointerException
Deep vs Shallow Comparison
Shallow Comparison:
Compares references only
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
int[] arr3 = arr1;
System.out.println(arr1 == arr2); // false (different objects)
System.out.println(arr1 == arr3); // true (same reference)
Deep Comparison:
Compares actual content
import java.util.Arrays;
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
System.out.println(Arrays.equals(arr1, arr2)); // true (same content)
Exam Tips
Remember:
- Primitives: Use
==for comparison - Objects: Use
equals()for content comparison - Strings: Always use
equals()orequalsIgnoreCase() - == operator: Compares references (memory addresses)
- equals() method: Compares content (values)
- Null safety: Check null before calling equals()
- String pool: Literals may share same object
- Case sensitivity:
equals()is case-sensitive
Common Questions:
- Difference between == and equals()
- Why use equals() for String comparison?
- What is String pool?
- How to avoid NullPointerException in equality check?
- What is equalsIgnoreCase()?
- When to use == vs equals()?
- How to override equals() in custom class?
- What is Objects.equals()?
Quick Reference:
// Primitives
int a = 10, b = 10;
a == b; // true
// Strings
String s1 = "Hello";
String s2 = "Hello";
s1.equals(s2); // true ✓ Correct way
s1 == s2; // May be true (pool) or false
// Objects
Object obj1 = new Object();
Object obj2 = new Object();
obj1.equals(obj2); // false (different objects)
obj1 == obj2; // false (different references)