Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
How equals() and hashCode() Work in Java and Why Following Their Contract Matters
BackEnd DevelopmentJava

How equals() and hashCode() Work in Java and Why Following Their Contract Matters

A Comprehensive Overview

Eugene Obiedkov

by Eugene Obiedkov

Full Stack Developer

Feb, 2025
8 min read

facebooklinkedintwitter
copy
How equals() and hashCode() Work in Java and Why Following Their Contract Matters

In Java, the contract of the equals() and hashCode() methods is a crucial aspect of working with collections like HashMap, HashSet, and other data structures that rely on hashing.

Properly overriding these methods ensures correct object behavior in such collections and helps prevent common errors. The contract between these methods is closely linked, and failing to follow it can lead to unexpected results in a program.

The Contract of the equals() Method

The equals() method is used to check if two objects are equal. By default, the equals() method in the Object class compares objects by reference, meaning it returns true only if both objects point to the same memory location. However, in most cases, if objects are logically equal, this method should be overridden to compare the data inside the objects instead of their references.

The contract of the equals() method requires it to follow these rules:

RuleDescription
ReflexivityFor any objectx, the expressionx.equals(x)must always returntrue.
SymmetryIfx.equals(y)returnstrue, theny.equals(x)must also returntrue.
TransitivityIfx.equals(y)returnstrueandy.equals(z)returnstrue, thenx.equals(z)must also returntrue.
ConsistencyIf two objects are equal, multiple calls tox.equals(y)must return the same result, provided the objects do not change.
Non-nullityx.equals(null)must always returnfalse.

Example of overriding the equals() method:


Note iconNote
This method is usually generated by the IDE you are using, so you typically don’t need to write it manually.

Run Code from Your Browser - No Installation Required

Run Code from Your Browser - No Installation Required

The Contract of the hashCode() Method

The hashCode() method returns an integer hash code for an object, which is used in hash-based collections like HashMap and HashSet for efficient lookup and object organization. The contract of the hashCode() method requires it to follow these rules:

  • If two objects are equal according to the equals() method, their hash codes must be the same. This is the key principle that ensures proper behavior in collections like HashMap, where elements are located using hash codes;
  • If two objects are not equal, their hash codes can be different, but they don’t have to be—two distinct objects may have the same hash code (a hash collision). However, too many collisions can reduce performance;
  • Consistency: If an object does not change, its hash code must remain consistent across multiple calls to hashCode().

Example of overriding the hashCode() method:


Note iconNote
The hashCode() method is typically generated by your IDE, which produces the most efficient version. Writing it manually is usually unnecessary.

The Relationship Between equals() and hashCode()

The equals() and hashCode() methods are closely linked: if two objects are equal according to equals(), they must have the same hash code. This is essential for the correct functioning of hash-based collections.

For example, if two objects considered equal have different hash codes, they may end up in different "buckets" inside a hash table, leading to incorrect lookups and unpredictable behavior.

What Happens If You Override Only equals() or hashCode()?

If you override only one of these methods but not both, it can lead to problems with storing and retrieving objects in hash-based collections like HashMap and HashSet.

Overriding only equals() but not hashCode()

If you override equals() but leave hashCode() as the default implementation:

Objects that are logically equal according to equals() may have different hash codes, which violates the contract. This can cause incorrect behavior in collections like HashMap and HashSet.

Here, we added new Car("Toyota", 2020) to the HashMap and then tried to retrieve it using another new Car("Toyota", 2020).

The equals() method says the objects are equal. But since hashCode() is not overridden, HashMap assigns them different hash codes. As a result, HashMap looks for the key in the wrong bucket and doesn’t find it, returning null.

Overriding only hashCode() but not equals()

If you override hashCode() but leave equals() as the default implementation:

Objects that are logically equal (should be considered the same) will end up in the same bucket because of their identical hash codes. However, since HashMap uses equals() to check for key equality inside the bucket, and equals() still compares by reference, it won’t recognize them as equal.

Even if hashCode() correctly returns the same value for logically equal objects, the lookup inside HashMap will fail because equals() will still compare them by reference.

Start Learning Coding today and boost your Career Potential

Start Learning Coding today and boost your Career Potential

Summary

The contract between equals() and hashCode() is fundamental for objects to behave correctly in Java collections that rely on hashing. Violating this contract can lead to unexpected bugs, incorrect collection behavior, and reduced performance. Always override both methods together, following best practices, to avoid these issues and ensure your code works reliably.

FAQs

Q: What is the purpose of the equals() method in Java?
A: The equals() method is used to compare two objects for logical equality. By default, it checks if two references point to the same memory location, but it can be overridden to compare objects based on their actual data.

Q: Why do we need to override hashCode() when overriding equals()?
A: Java collections like HashMap and HashSet rely on hashCode() for efficient lookup. If two objects are considered equal according to equals(), they must have the same hashCode(). Otherwise, collections may fail to find elements, leading to unexpected behavior.

Q: What happens if I override equals() but not hashCode()?
A: Objects that are logically equal may have different hash codes, violating the hashCode() contract. This can cause issues in hash-based collections, such as HashMap not being able to find a key even if it was added earlier.

Q: What happens if I override hashCode() but not equals()?
A: Even if hashCode() correctly groups objects into the same bucket in a HashMap, the lookup inside that bucket fails because equals() (which still compares by reference) does not recognize them as equal.

Q: Can two different objects have the same hash code?
A: Yes, this is called a hash collision. Multiple objects can have the same hash code, but equals() is used as a second check to confirm actual equality.

Was this article helpful?

Share:

facebooklinkedintwitter
copy

Was this article helpful?

Share:

facebooklinkedintwitter
copy

Content of this article

Follow us

trustpilot logo

Address

codefinity
We're sorry to hear that something went wrong. What happened?
some-alt