I was surprised by the fact that Map<?,?> is not a Collection<?>.
I thought it’d make a LOT of sense if it was declared as such:
public interface Map<K,V> extends Collection<Map.Entry<K,V>>
After all, a Map<K,V> is a collection of Map.Entry<K,V>, isn’t it?
So is there a good reason why it’s not implemented as such?
Thanks to Cletus for a most authoritative answer, but I’m still wondering why, if you can already view a Map<K,V> as Set<Map.Entries<K,V>> (via entrySet()), it doesn’t just extend that interface instead.
If a
Mapis aCollection, what are the elements? The only reasonable answer is “Key-value pairs”
Exactly, interface Map<K,V> extends Set<Map.Entry<K,V>> would be great!
but this provides a very limited (and not particularly useful)
Mapabstraction.
But if that’s the case then why is entrySet specified by the interface? It must be useful somehow (and I think it’s easy to argue for that position!).
You can’t ask what value a given key maps to, nor can you delete the entry for a given key without knowing what value it maps to.
I’m not saying that that’s all there is to it to Map! It can and should keep all the other methods (except entrySet, which is redundant now)!
From the Java Collections API Design FAQ:
Update: I think the quote answers most of the questions. It’s worth stressing the part about a collection of entries not being a particularly useful abstraction. For example:
would allow:
(assuming an
entry()method that creates aMap.Entryinstance)Maps require unique keys so this would violate this. Or if you impose unique keys on aSetof entries, it’s not really aSetin the general sense. It’s aSetwith further restrictions.Arguably you could say the
equals()/hashCode()relationship forMap.Entrywas purely on the key but even that has issues. More importantly, does it really add any value? You may find this abstraction breaks down once you start looking at the corner cases.It’s worth noting that the
HashSetis actually implemented as aHashMap, not the other way around. This is purely an implementation detail but is interesting nonetheless.The main reason for
entrySet()to exist is to simplify traversal so you don’t have to traverse the keys and then do a lookup of the key. Don’t take it as prima facie evidence that aMapshould be aSetof entries (imho).