In Java, the hash code of a String is computed only once and then cached, making lookups in hash-based collections (HashMap, HashSet, Hashtable) faster.
How Hash Code Works in String
- The
hashCode()method inStringcomputes a hash value based on the characters in the string. - Since
Stringis immutable, its hash code never changes once calculated. - Java stores (caches) the computed hash code in an instance variable, so it doesn’t need to recalculate it every time
hashCode()is called.
Where is the Hash Code Cached?
The String class has an instance variable (private int hash) that stores the cached hash code.
🔹 Inside the String class (java.lang.String):
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[]; // Character array storing the string data
private int hash; // Cached hash code (default 0)
@Override
public int hashCode() {
int h = hash; // Read cached hash
if (h == 0 && value.length > 0) { // If hash not computed yet
for (char c : value) {
h = 31 * h + c; // Compute hash using 31-based formula
}
hash = h; // Cache the computed hash
}
return h;
}
}
👉 Key Observations:
- If
hash == 0, the hash code is computed and cached. - If
hashCode()is called again, Java returns the cached value, avoiding recomputation.
Example: Cached Hash Code in Action
public class StringHashCodeExample {
public static void main(String[] args) {
String s = "Hello";
// First call: hash code is computed and cached
System.out.println(s.hashCode()); // Example output: 69609650
// Second call: returns the cached value
System.out.println(s.hashCode()); // Same output: 69609650
}
}
👉 Benefit: No need to recalculate the hash every time, making operations faster.
Why is Caching Hash Code Useful in Hash-Based Collections?
When you use a String as a key in a HashMap or HashSet, Java frequently calls hashCode() for:
- Finding the correct bucket (index) in the hash table.
- Checking for equality in case of hash collisions.
Example: Using String in HashMap
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("Java", 1);
map.put("Python", 2);
// Uses the cached hash code to locate "Java"
System.out.println(map.get("Java")); // Output: 1
}
}
🛑 Without caching: Every lookup (map.get("Java")) would require recomputing the hash code.
✅ With caching: The hash is stored inside the string, making lookups faster.
Key Benefits of Hash Code Caching in Strings
| Benefit | Explanation |
|---|---|
| Faster Hash-Based Lookups | hashCode() does not need to be recomputed every time. |
| Reduces CPU Workload | Prevents unnecessary recalculations, improving performance. |
Improves HashMap, HashSet, Hashtable Efficiency | Faster retrieval of keys in hash-based collections. |
Conclusion
✅ The hash code of a String is stored in a private hash variable to avoid recomputation.
✅ This caching mechanism makes HashMap and HashSet operations faster when String is used as a key.
✅ Since String is immutable, the cached hash code remains valid for the object’s lifetime.