views:

126

answers:

1

I'm using the com.google.common.collect.ArrayListMultimap<K,V> collection to map Integers to Strings. The class provides a method called containsValue(Object value) which checks if the multimap contains the specified value for any key. Once I determine that is true, what's the best way to retrieve said key?

ArrayListMultimap<String, Integer> myMap = ArrayListMultimap.create();

if (myMap.containsValue(new Integer(1))
{
   // retrieve the key? 
}
+2  A: 

Instead of using containsValue you could iterate over myMap.entries() which returns a collection of all key-value pairs. The iterator generated by the returned collection traverses the values for one key, followed by the values of a second key, and so on:

Integer toFind = new Integer(1);
for (Map.Entry<String, Integer> entry: myMap.entries()) {
    if (toFind.equals(entry.getValue())) {
        // entry.getKey() is the first match
    }
}
// handle not found case

If you look at the implementation of containsValue in StandardMultimap it just iterates over the map's values so the performance of doing this with map.entries() instead of map.values() should be about the same.

public boolean containsValue(@Nullable Object value) {
    for (Collection<V> collection : map.values()) {
      if (collection.contains(value)) {
        return true;
      }
    }

    return false;
}

In the general case of course there isn't necessarily a unique key for a given value so unless you know that in your map each value only occurs against a single key you would need to specify the behaviour e.g. if you wanted the first key or last key.

mikej