Because of 2 things:
This is the implementation of hashCode()
for String
:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
For one-character strings, it's simply the Unicode value of that character. Those letters (A-E) have consecutive values (65-69).
The HashMap
class modifies the hash a little bit, but in this case with such low values, the value is unaffected.
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
HashMap
will reduce the hash code modulo the number of buckets to find the bucket number for the key. In this case, the bucket number are all sequential -- 1
, 2
, 3
, 4
, 5
. So, the iterator iterated over the buckets in order.
If any of these things were to happen, some of which are not in the HashMap
contract and are not in your control, then the iteration order may change.
- Add other keys that don't have the same quotient modulo 16, e.g. "Z", "a", "AA".
- Create a map with a smaller default capacity.
- Java decides to mess with the
hash
method internal to HashMap
.
- Java decides to mess with the algorithm mapping the hash code to the bucket number internal to
HashMap
.
- Java decides to mess with the
hashCode
method in String
.