In Java, objects are responsible for their equals/hashCode implementations. The contract they must abide by is:
1. If two objects are equal, they must produce the same hash code; and
2. If they are not equal, they may produce the same hash code.
So if you had a list of 10 Strings and put them in a map in Java, it's likely you'll get a deterministic order for iterating over them unless you added a random factor. That factor could be a random seed tied to the map that you XOR the hash code with.
You can't really change the hash code itself to avoid a Hash DoS attack because you might break that contract. So how does Go (and Rust?) deal with that? Is Go adding a random seed to each hash map? If not, what is it doing?
As for nullability, there's no going back once you use a type system that expresses nullability.
Lastly, PHP arrays are incredibly convenient, ignoring the weirdness with them being array and hash map hybrids. But th ekey aspect is that they maintain insertion order when you use them like a map. This is so often what you want. Yes, other langauges do this too (eg Java's LinkedHashMap) but it's (IMHO) such a useful default.
What you do is have a "family" of hash functions. The random seed value chooses a new hash function. The same properties apply to each individual map's hash function, but each map has a different hash function
Secondary, go map iteration starts from a random position in the hashmap. The order on subsequent iterations is the same, but rotated as a result of the random start index
You don't use the object hash as the key directly. You combine it with a value chosen randomly per-map using a function that works hard to erase correlations between the input object hash and the output table location.
In Java, objects are responsible for their equals/hashCode implementations. The contract they must abide by is:
1. If two objects are equal, they must produce the same hash code; and
2. If they are not equal, they may produce the same hash code.
So if you had a list of 10 Strings and put them in a map in Java, it's likely you'll get a deterministic order for iterating over them unless you added a random factor. That factor could be a random seed tied to the map that you XOR the hash code with.
You can't really change the hash code itself to avoid a Hash DoS attack because you might break that contract. So how does Go (and Rust?) deal with that? Is Go adding a random seed to each hash map? If not, what is it doing?
As for nullability, there's no going back once you use a type system that expresses nullability.
Lastly, PHP arrays are incredibly convenient, ignoring the weirdness with them being array and hash map hybrids. But th ekey aspect is that they maintain insertion order when you use them like a map. This is so often what you want. Yes, other langauges do this too (eg Java's LinkedHashMap) but it's (IMHO) such a useful default.