The order will not change (in practice) unless you add / remove something to your HashSet
.
The order is based on the internal hashtable buckets. And that depends on both the hashCode()
of an object and the size of the hashtable.
Simplified example:
A's hashcode is 10, B's hashCode is 11. The hastable has size 2.
The mapping from hash code to position in hashtable would be purely based on the last bit, i.e. even hashcodes go into table[0], odd ones into table[1].
table[0] = { A }
table[1] = { B }
Iterating over those values would most likely be A, B now. And that result should be reproducible each time as long as table size stays the same.
Adding a third element C with hashCode 12 would (when not resizing the table) add it to bucket #0 as well.
table[0] = { A, C }
table[1] = { B }
So your iteration would be A, C, B. Or depending in whether you inserted A before C: C, A, B
Adding elements will in practice resize the table and re-hash using an adjusted mapping. E.g. table size would be doubled and the last 2 bits could be used to determine the bucket
table[0] = { C }
table[1] = { }
table[2] = { A }
table[3] = { B }
And the order would have changed completely by adding just 1 element.