There are questions here how to get a Maps keys associated with a given value, with answers pointing to google collections (for bidirectional maps) or essentially saying “loop over it”.
I just recently noticed that the Map interface has a boolean containsValue(Object value) method that “will probably require time linear in the map size for most implementations of the Map interface” and the implementation in AbstractMap indeed iterates over the entrySet().
What could be the reason for the design decision to include containsValue in Map, but no Collection<V> getKeysForValue(Object)? I can see why one would omit both, or include both, but if there is one, why not the other?
One thing that came to my mind is that it would require any Map implementation to know about a Collection implementation for the return value, but that is not actually a good reason as the Collection<V> values() method also returns a collection (an anonymous new AbstractCollection<V>() in case of AbstractMap).
Maps can return a
Collectionof their keys and values since 1.2, so it was trivial to look for a value:public Object containsValue(Object v) {return values().contains(v);}This method uses natively optimisations fromvalues()andcontains()for any implementation ofMap, but is likely to be slow anyway in most of them…The
getKeysForValue(Object)you’re looking for is NOT trivial. It requires a specific algorithm, and this algorithm cannot be made generic enough, it must be optimised for every implmentation ofMap.It could be the reason, or it is simply that the Collection API is full of this kind of little loopholes…