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 inString
computes a hash value based on the characters in the string. - Since
String
is 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.