While Holloway has answered the question itself, I'd like to clear up a minor misconception.
String
is only immutable in the sense that it doesn't expose functionality for mutating it. However, it still does have an internal mutable state, specifically the hash
field.
Calculating the hash of a String
is a relatively simple O(n) operation. Not disastrous, but also not completely free, especially not for longer strings.
Since strings are a fundamental part of almost all aspects of Java and used basically everywhere, including in Java-internal functionality, ensuring good performance for the implementation of String
is critical. Even a minor inefficiency may be enormously multiplied simply from how incredibly often it gets run. As such, while the hash calculation isn't too bad, it's still something we'd like to not have to do unless it's absolutely necessary.
Now, there are three ways we could go about calculating the hash:
- We calculate it every time
hashCode()
is called. In other words, we only calculate it when we need it. However, that also means we have to recalculate it every single time it's needed. This would be disastrous for HashMap
and similar.
- Calculate it once when we create the string, then return the same value every time
hashCode()
is called. This makes hashCode()
free, but makes the creation of a string more expensive for the situations where the hash isn't needed. Since a lot of strings are constantly created in Java, that's a non-negligible.
- We do it lazily, i.e. we calculate it the first time
hashCode()
is called and then remember it for subsequent calls to hashCode()
.
The latter option was chosen since it finds that sweet spot between "don't calculate it unless you need it" and "don't calculate it more than once". This does mean that String
has a mutable state; it updates its internal cache of the hash code. However, from an outside observer, this effect is invisible (aside from the fact that the first call to hashCode()
is slightly slower), meaning that the string is effectively immutable.