Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are keys immutable in Java?

Tags:

java

hashtable

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?

like image 641
playitright Avatar asked Dec 03 '15 08:12

playitright


People also ask

Why keys are immutable in HashMap?

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.

Why is immutable in Java?

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.

What happens if key of a HashMap is mutable?

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.

Are map keys immutable?

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.


1 Answers

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;
}
like image 144
weston Avatar answered Oct 27 '22 20:10

weston