Apologies for the fairly naive question, but I believe my own answer to be naive. I think keys (in HashTables) are immutable because we wouldn't want to somehow accidentally alter a key and therefore mess with the sorting of the HashTable. Is this a correct explanation? If so, how can it be more correct?
Immutabiility is required, in order to prevent changes on fields used to calculate hashCode() because if key object return different hashCode during insertion and retrieval than it won't be possible to get object from HashMap.
In object-oriented programming, the immutable string or objects that cannot be modified once it is created. But we can only change the reference to the object. We restrict to change the object itself. The String is immutable in Java because of the security, synchronization and concurrency, caching, and class loading.
If key's hash code changes after the key-value pair (Entry) is stored in HashMap, the map will not be able to retrieve the Entry. Key's hashcode can change if the key object is mutable. Mutable keys in HahsMap can result in data loss.
Map's keys can be of any type, and use Immutable.is to determine key equality. This allows the use of any value (including NaN) as a key. Because Immutable.is returns equality based on value semantics, and Immutable collections are treated as values, any Immutable collection may be used as a key.
During the HashTable.put
the key is hashed and it an its value are stored in one of a number of buckets (which are lists of key value pairs) based on the hash, for example something like:
bucket[key.hashcode() % numberOfBuckets].add(key, value)
If the key's hashcode
changes after insertion it could then be in the wrong bucket and you would then not be able to find it and the hashtable would incorrectly return null
on any get
for that key.
Aside: Understanding the inner workings of a hashtable helps you understand the importance of a good quality hashcode
function for your keys. As a poor hashcode function could result in a poor distribution of keys in buckets. And as buckets are just lists, this results in a lot of linear searches which greatly reduces the effectiveness of the hashtable. e.g. this terrible hashcode function puts everything in one bucket, so it's effectively just one list.
public int hashcode { return 42; /*terrible hashcode example, don't use!*/ }
This is also one reason why prime numbers appear in good hashcode functions, e.g.:
public int hashcode {
int hash = field1.hashcode();
hash = hash*31 + field2.hashcode(); //note the prime 31
hash = hash*31 + field3.hashcode();
return hash;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With