I opened HashMap source code (Java 8+) and checked the put() method. In Java 7 (and less) the source code was kinda simple, but I can't understand the Java 8+ version.
If element in bucket doesn't exist, we just put it into HashMap:
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
But if element already exist we meet collision.
At the beginning in "else" block we compare element (?) with (what? first element in this bucket?) by their hash(?):
else {
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
But, wait, we did it again later there:
...
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
...
}
We traversed the list until the end and compared the new element with all elements (for loop) in bucket. So, I don't understand the purpose of the first comparison. Does it (first case) mean that we compare last added element (already in hashmap) with new "ready to add" element if they are not in same bucket?