Looking java's hashmap implementation, not able to understand the reason behind some lines. In below code copied from here, in line 365-367, I am not able to understand why have they done the assignment of e.key to k first and then compared == with key [ (k = e.key) == key ]. Why not directly do (e.key == key) . This pattern appears several times in code.
359
360 final Entry<K,V> getEntry(Object key) {
361 int hash = (key == null) ? 0 : hash(key.hashCode());
362 for (Entry<K,V> e = table[indexFor(hash, table.length)];
363 e != null;
364 e = e.next) {
365 Object k;
366 if (e.hash == hash &&
367 ((k = e.key) == key || (key != null && key.equals(k))))
368 return e;
369 }
370 return null;
371 }
Hashmap uses the array of Nodes(named as table), where Node has fields like the key, value (and much more). Here the Node is represented by class HashMapEntry. Basically, HashMap has an array where the key-value data is stored. It calculates the index in the array where the Node can be placed and it is placed there.
Whenever two different objects have the same hash code, we call this a collision. A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap lookup has to look again to find the right object.
A simple thumb rule is to use immutable objects as keys in a HashMap . because: If it were mutable, then the hashcode() value or equals() condition might change, and you would never be able to retrieve the key from your HashMap .
Internally HashMap uses a hashCode of the key Object and this hashCode is further used by the hash function to find the index of the bucket where the new entry can be added. HashMap uses multiple buckets and each bucket points to a Singly Linked List where the entries (nodes) are stored.
This is probably a matter of optimization. Calling e.key
adds a level of indirection (as you use the reference on e
to get a reference on key
). The variable k
allows to have a shortcut for e.key
and avoids using this unnecessary indirection twice.
The implementation also directly use the result of the assignation k = e.key
instead of assigning the value to k
and then compare k
to key
.
I do not know if the impact of such an optimization is significant (assigning a new variable vs indirect access). It is probably tricky to evaluate, and it may be dependent on the JVM (as different JVM may perform different optimization on the code).
As HashMap is widely used in Java, I guess the implementation aims to offer maximum performance without expecting any optimization from the execution environment; hence, the common use of this pattern.
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