我很惊讶 Map<?,?>
不是 Collection<?>
.
我认为如果这样声明它会很有意义:
public interface Map<K,V> extends Collection<Map.Entry<K,V>>
毕竟,Map<K,V>
是 Map.Entry<K,V>
的集合,不是吗?
那么是否有充分的理由不这样做?
感谢 Cletus 提供最权威的答案,但我仍然想知道为什么,如果您已经可以查看 Map<K,V>
作为 Set<Map.Entries<K,V>>
(通过 entrySet()
),它不只是扩展该接口(interface)。
If a
Map
is aCollection
, what are the elements? The only reasonable answer is "Key-value pairs"
没错,interface Map<K,V> extends Set<Map.Entry<K,V>>
会很棒!
but this provides a very limited (and not particularly useful)
Map
abstraction.
但如果是这样,那为什么是 entrySet
由接口(interface)指定?它一定是有用的(而且我认为很容易为这个立场争论!)。
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.
我并不是说 Map
的全部内容!它可以并且应该保留所有其他方法(entrySet
除外,现在是多余的)!
最佳答案
来自 Java Collections API Design FAQ :
Why doesn't Map extend Collection?
This was by design. We feel that mappings are not collections and collections are not mappings. Thus, it makes little sense for Map to extend the Collection interface (or vice versa).
If a Map is a Collection, what are the elements? The only reasonable answer is "Key-value pairs", but this provides a very limited (and not particularly useful) Map abstraction. 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.
Collection could be made to extend Map, but this raises the question: what are the keys? There's no really satisfactory answer, and forcing one leads to an unnatural interface.
Maps can be viewed as Collections (of keys, values, or pairs), and this fact is reflected in the three "Collection view operations" on Maps (keySet, entrySet, and values). While it is, in principle, possible to view a List as a Map mapping indices to elements, this has the nasty property that deleting an element from the List changes the Key associated with every element before the deleted element. That's why we don't have a map view operation on Lists.
更新:我认为这句话回答了大部分问题。值得强调的是,条目集合不是特别有用的抽象。例如:
Set<Map.Entry<String,String>>
允许:
set.add(entry("hello", "world"));
set.add(entry("hello", "world 2"));
(假设有一个创建 Map.Entry
实例的 entry()
方法)
Map
需要唯一的键,所以这会违反这一点。或者,如果您对条目的 Set
施加唯一键,则它实际上并不是一般意义上的 Set
。这是一个 Set
有更多限制。
您可以说 Map.Entry
的 equals()
/hashCode()
关系纯粹是关键,但即便如此问题。更重要的是,它真的增加了任何值(value)吗?一旦您开始研究极端案例,您可能会发现这种抽象会崩溃。
值得注意的是,HashSet
实际上是作为HashMap
实现的,而不是相反。这纯粹是一个实现细节,但仍然很有趣。
entrySet()
存在的主要原因是为了简化遍历,因此您不必遍历键然后查找键。不要将其作为 Map
应该是条目的 Set
的初步证据(恕我直言)。
关于java - 为什么 Java Map 不扩展 Collection?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2651819/