HashCode and Equals Method in Java
Introduction
In Java, the hashCode()
and equals()
methods are fundamental to working with objects efficiently, especially in collections like HashMap
, HashSet
, and HashTable
. These methods help determine object equality and facilitate efficient storage and retrieval operations.
This article will provide a deep dive into the significance of hashCode()
and equals()
, their default implementations, best practices, and how to correctly override them.
Understanding equals()
Method
The equals()
method in Java is defined in the Object
class and is used to compare objects for equality.
Default Implementation of equals()
By default, the equals()
method in the Object
class checks for reference equality (i.e., whether two object references point to the same memory location).
class Sample {
int id;
Sample(int id) {
this.id = id;
}
}
public class EqualsExample {
public static void main(String[] args) {
Sample obj1 = new Sample(1);
Sample obj2 = new Sample(1);
System.out.println(obj1.equals(obj2)); // false
}
}
Since equals()
is not overridden, it behaves like ==
, checking if both references point to the same object.
Overriding equals()
for Logical Equality
To compare objects based on their content, override equals()
:
class Sample {
int id;
Sample(int id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Sample sample = (Sample) obj;
return id == sample.id;
}
}
Now, equals()
checks if two objects have the same id
value.
Understanding hashCode()
Method
The hashCode()
method returns an integer hash code for an object. It is used in hash-based collections to optimize storage and retrieval operations.
Default Implementation of hashCode()
The default implementation of hashCode()
in the Object
class generates a unique integer (memory-based), meaning two different objects may have different hash codes even if they are logically equal.
Sample obj1 = new Sample(1);
Sample obj2 = new Sample(1);
System.out.println(obj1.hashCode()); // e.g., 366712642
System.out.println(obj2.hashCode()); // e.g., 1829164700
Overriding hashCode()
If equals()
is overridden, hashCode()
must also be overridden to ensure consistency. The general contract states that:
-
If two objects are equal according to
equals()
, theirhashCode()
values must be the same. -
If two objects are unequal, their
hashCode()
values should ideally be different for better performance.
@Override
public int hashCode() {
return Integer.hashCode(id);
}
Best Practices for Overriding hashCode()
-
Use the same fields in
hashCode()
andequals()
. -
Use prime numbers (like 31) in hash computation for better distribution.
-
Use built-in utility methods like
Objects.hash()
,Integer.hashCode()
, etc. -
Ensure consistency—an object's hash code should not change during execution unless modified.
Importance in Hash-Based Collections
Example with HashSet
import java.util.HashSet;
class Employee {
int id;
String name;
Employee(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Employee employee = (Employee) obj;
return id == employee.id && name.equals(employee.name);
}
@Override
public int hashCode() {
return 31 * id + name.hashCode();
}
}
public class HashSetExample {
public static void main(String[] args) {
HashSet<Employee> employees = new HashSet<>();
employees.add(new Employee(1, "Alice"));
employees.add(new Employee(1, "Alice"));
System.out.println(employees.size()); // 1 (avoids duplicates)
}
}
Common Mistakes to Avoid
-
Not overriding
hashCode()
when overridingequals()
: Leads to issues in hash-based collections. -
Using mutable fields in
hashCode()
: If an object's hash code changes after being inserted into a hash-based collection, it may become inaccessible. -
Not checking for
null
inequals()
: Can causeNullPointerException
.
Conclusion
The hashCode()
and equals()
methods play a crucial role in determining object equality and optimizing storage in hash-based collections. Understanding and correctly implementing them ensures efficiency and consistency in Java applications.
Sign up here with your email
ConversionConversion EmoticonEmoticon