Most languages implement sets using maps. The only major difference you can optimise for is the fact that in majority usage, keys in maps are likely to exist, whereas sets are used for membership checks. Bar that, you can just as well use a map with a dummy value.
back
1 comments
Can you give a reference for that? It sounds very unlikely to me, although I've only read/gone through two relevant standard library implementations: F# and OCaml.
Neither of them use dummy values as you suggest. They have similar implementations (both are AVL trees) but sets really do contain only one value while maps contain two. I would be surprised if many other languages did as you suggest.
Rust's HashSet is a HashMap mapping to "()", which is Rust's equivalent to "void".
That is true for the internal implementation details but HashSet provides a different API, it is not just a type alias. So you don't have to worry about semantics of what the values mean (like the bools in Go), and it has no size overhead.
Python, Ruby, Perl. Languages where hashmaps are a builtin.
Python has its own set type not based on hashmap/dict, and that's been the case for years.
The set implementation points out some of the differences, at https://github.com/python/cpython/blob/main/Objects/setobjec... :
Unlike the dictionary implementation, the lookkey function can return
NULL if the rich comparison returns an error.
Use cases for sets differ considerably from dictionaries where looked-up
keys are more likely to be present. In contrast, sets are primarily
about membership testing where the presence of an element is not known in
advance. Accordingly, the set implementation needs to optimize for both
the found and not-found case.Java as well: https://github.com/pengisgood/jdk-source-code/blob/master/sr...
EDIT : and Rust: https://docs.rs/hashbrown/latest/hashbrown/hash_set/index.ht... (this is used by the default implementation of HashSet).
Update: Looks like I had good reason to be surprised. Thanks everyone for the examples.