Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can i have HashSets as the keys in a HashMap? Suggest an alternative if not

Edit: explained the problem properly now.

I have a hashmap where i want to store sets of words seen together (key) and the lines in which they were seen together(value). This is the structure i came up with:

HashMap<HashSet<String>, HashSet<Integer>> hm= ...

for inputs:

  1. mango, banana, apple

  2. apple, banana

  3. peach, walrus

  4. walrus, peach

As I read this, line by line, I make new temporary keys (hashsets not yet inserted into hashmap) from the combination of words in the line. Each temporary key is a hashset of a subset of the words in the line. If a temporary key already exists in my hashmap, which i check by

if(hashmap.containsKey(hashset))

i simply add the new line to that key's corresponding value, if not, I make a new entry in the hashmap and take care of it.

At no point do i change an existing key. I only update their corresponding values in the hasmmap.

my hashmap, at the end of reading the file, should look something like this

[apple, banana]=[1,2]

[peach, walrus]=[3,4]

...

the problem is that the

if(hashmap.containsKey(hashset))

piece of code doesn't always detect existing keys. Why is this? Is this structure not allowed?

Thank you

like image 514
student101 Avatar asked Mar 19 '12 16:03

student101


1 Answers

This should work, but you need to watch out for mutability of the keys. If you ever change the contents of one of the keys, its hashcode will change, and your map will start doing strange things. From the javadoc for Map:

Note: great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map. A special case of this prohibition is that it is not permissible for a map to contain itself as a key. While it is permissible for a map to contain itself as a value, extreme caution is advised: the equals and hashCode methods are no longer well defined on such a map.

To avoid this, wrap the keys with Collections.unmodifiableSet() immediately upon creation, or just use ImmutableSet from Guava.

like image 136
Matt McHenry Avatar answered Oct 06 '22 15:10

Matt McHenry