If you've prepared for Java interviews, you've probably encountered this question:
How does HashMap work internally in Java?
It's easy to memorize that HashMap stores key-value pairs. However, understanding how it stores entries, handles collisions, and retrieves values helps you write better Java code and answer interview questions confidently.
Let's break it down.
1. What is a HashMap?
HashMap is a Java collection that stores data as key-value pairs.
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 90);
scores.put("Bob", 85);
scores.put("Charlie", 95);
System.out.println(scores.get("Alice"));
}
}
Output:
90
A HashMap allows one null key and multiple null values. It doesn't guarantee iteration order, and it isn't thread-safe for concurrent modification without appropriate coordination.
2. How does HashMap store entries?
Internally, a typical Java HashMap implementation uses an array of buckets. Each entry contains a key, a value, a hash, and a reference to another entry when needed.
When you execute:
scores.put("Alice", 90);
Java broadly performs these steps:
- Calculates a hash based on the key.
- Uses the hash to determine a bucket index.
- Checks whether that bucket already contains an entry for the key.
- Inserts a new entry or updates the existing value.
The exact implementation details can vary between Java versions, but this is the fundamental idea.
3. What happens when two keys collide?
A collision occurs when different keys map to the same bucket.
For example, two different keys might produce the same bucket index even if their hash values differ.
HashMap handles collisions by storing multiple entries in the same bucket. In modern OpenJDK implementations, a bucket can use a linked list and may be converted into a balanced tree under certain conditions.
Treeification helps prevent long collision chains from degrading lookup performance excessively.
This is one reason a good understanding of hashCode() and equals() matters.
4. Why are hashCode() and equals() important?
Java uses hashCode() to help locate a bucket and equals() to determine whether keys are logically equal.
Consider this example:
String first = new String("Java");
String second = new String("Java");
System.out.println(first == second);
System.out.println(first.equals(second));
Output:
false
true
The two references point to different objects, but their contents are equal.
When implementing custom key classes, follow the contract: if two objects are equal according to equals(), they must return the same hash code.
Otherwise, a HashMap may not find a logically equivalent key as expected.
5. What is the time complexity?
Typical expected time complexity for basic HashMap operations is:
| Operation | Expected complexity |
|---|---|
put() |
O(1) |
get() |
O(1) |
remove() |
O(1) |
These are expected or average-case descriptions, not unconditional guarantees. Performance depends on hashing, collisions, resizing, and implementation details.
6. When should you use HashMap?
HashMap is useful when you need to:
- Count the frequency of elements.
- Store user details by ID.
- Cache calculated results.
- Perform fast key-based lookups.
- Group or aggregate data.
For example, counting word frequency is a common interview exercise:
Map<String, Integer> frequency = new HashMap<>();
String[] words = {"java", "spring", "java", "sql"};
for (String word : words) {
frequency.merge(word, 1, Integer::sum);
}
System.out.println(frequency);
The map's iteration order is unspecified, so the printed order may vary.
7. Interview questions to practice
Once you understand the fundamentals, try answering these questions without looking at the explanation:
- What happens internally when you call
put()? - How does HashMap handle collisions?
- What happens when two keys have the same hash code?
- Why should equal objects have equal hash codes?
- How does resizing work?
- Why is HashMap not thread-safe?
- When can a bucket become a tree?
Being able to explain the reasoning is more valuable than memorizing a short definition.
Continue your Java interview preparation
I'm building InstantInterviewPrep.com, a resource for developers preparing for technical interviews.
You can explore the Java interview questions and answers and the Core Java learning guide for more topics to study.
If you're preparing for a Java interview, which topic do you find most challenging: Collections, multithreading, JVM internals, or Spring Boot?
Top comments (0)