As far as HashMap.keys() called twice returns the keys in the same order (and it does in all versions of Java so far), the two #list-s will print the keys in the same order (assuming that the set of keys in the backing Map wasn't changed between the two). The documentation just means that some Map-s, in particular HashMap, have a key order that's random as far the (average) user is concerned.
Some details: #list and ?keys are straightforward, they don't mess with ordering, they just call the appropriate TemplateModel methods to list the keys. The ObjectWrapper is the trickier one; this is what wraps Map-s into TemplateModel-s. Legacy configurations use SimpleHash to wrap Map-s, which is known to change key order in some cases compared to the original Map, but only when it's created, not when it's later read. SimpleHash copies the original Map into an internal Map, and in case the original was a HashMap, it copies it into another HashMap, so the behavior will be similar (though the actual key order will be possibly different). More modern configurations use DefaultMapAdapter, which doesn't change the key order of the wrapped Map, as it's just an adapter. So in that case, as far as the wrapped Map always returns the keys in the same order, FreeMarker does too.