In the first place this is an error of RTFM kind. The "problem" behaviour is literally documented in the docs. However, in the second place, this is the wrong solution for the original problem. (The author links to <a href="https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/" rel="nofollow">https://andrewlock.net/why-is-string-gethashcode-different-e...</a> )<p>The original problem is using linked lists to handle hash collisions. Assuming this is what you want (to keep all values rather than discarding old values, like e.g. Python's dict objects do) obviously you should use a data structure that can handle the case of lots of collisions well, or check your user input.<p>At the very least the function should have a name that reflects its behaviour, eh? "GetUnguessableHashCode()" or something?<p>This reminds me of the recent fiasco over in Python land where somebody noticed that int() called on large strings can block the interpreter. The obvious solution is to add an optional timeout parameter (the problem is in the time domain after all.) Instead they added a limit to the size of strings you can pass to int()!
The article seems incomplete without bringing in the code or test that relied on the hash code. Was the test unnecessarily strict? Was code assuming more than a collection guarantees?
I wonder if a type system could track nondeterminism and prevent it. E.g. you couldn't just loop over a set, you'd have to order it, or apply a commutative operation. It would fit well into concurrency too, where nondeterminism is easily introduced.<p>I'm sure there are languages which do this, I seem to recall seeing it in Mercury
There's also HashMap randomization, that was introduced in JDK 9 to make certain kinds of attacks more difficult to perform.<p>The moral of the story should be: don't lean on undefined behavior.<p>If you care about iteration order, that's why there's a LinkedHashMap in the API.