You can easily see this in the implementation. If you look into the source of HashMap.put()
, you can see that the hash table index of the object is determined like this:
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
The methods hash()
and indexFor()
only ensure that there are not too many collisions of hash values and they don't exceed the length of the hash table.
Now if you take a look at Integer.hashCode()
, you'll see that the hash is the integer itself:
public int hashCode() {
return value;
}
So the integer which has the value 0
ends up in index 0
of the hash table and so on. At least as long as the hash table is big enough.
The toString()
method of HashMap
iterates over the hash table and the elements in each index of the hash table. So in your case the order is preserved.
As others mentioned correctly, this behavior is not ensured by implementations of Map
. It just works in this special case.