I found an interesting bug in my code today. I’m storing an object in a cache, and using a couple of indexes to address it. One index is a normal HashMap
object, which is indexing the object based on its unique ID. The other index is applying a grouping – several objects with the same grouping could exists so here I use a HashMap
indexing a HashSet
object. When I need to update the object, I call put
on the ID index, which updates the entry. For the grouping index, I get the HashSet
and call add
. I noticed that the unique ID index was updating, but the grouping index wasn’t – I had of course failed to read the documentation for HashSet
‘s add
method:
Adds the specified element to this set if it is not already present.
This contrasts with the HashMap
‘s put
method:
Associates the specified value with the specified key in this map. If the map previously contained a mapping for this key, the old value is replaced.
Now I should of read the documentation, but the reason for my mistake is that I knew that a HashSet
was actually backed by a HashMap
– as such I assumed add
would just call put
on the underlying HashMap
using the same object as a key and the value. Of course I am misusing a Set
here – a Set
is a collection of objects with no duplicates. When calling add
equals
is called, shows that the object is already there, and therefore doesn’t re-add it. Really I want the behaviour of a Map
with the simpler interface of a Set
, so I should just stop complaining and write my own wrapper class, shouldn’t I?
3 Responses to “Of HashSets and HashMaps”
… or just use HashMap. 😉
There’s no such thing as previous value for Set. It doesn’t make any sense to return ‘previous’ value from set since if there was a ‘previous’ value it’s ‘logically’ the same object that you are trying to insert.
Cameron, yes I could use a HashMap, but I’d probably wrap it to simplify the put method – the key and value will always be the same, and there are some other features (logging) that mcould be integrated into the class. I’d probably reuse this anyway, given the number of data strcutures I’ve got flying around right now.
Nipsu, that was kind of the point I was trying to make – I was annoyed initially for what appeared to be inconsistancies in the API’s between HashSet and HashMap, and then realised I was fundamentally misusing a Set.