Default implementation of hashcode provides the unique hashcode value for all object even has same information (different reference).
Hashcode implementation is required to ensure that the Object with same information (different reference) has equal hashcode.
The default implementation works fine if every object is unique. But if you override equals () then you are implicitly saying that objects with different addresses can be equivalent to each other. In that case you have to also override hashCode().
In String class, the two strings are equal and so their hash codes must be equal. But they are distinct objects with different addresses.
Using their addresses as hash codes would be an error (default unique for different addresses). Therefore, String overrides hashCode() to ensure that equal strings have equal hash codes. This helps meet hashCode()'s contract, which is:
Bottom line: If you override equals(), also override hashCode().