java - 为什么 Java Map 不扩展 Collection?

标签 java oop collections

我很惊讶 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 a Collection, 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.Entryequals()/hashCode() 关系纯粹是关键,但即便如此问题。更重要的是,它真的增加了任何值(value)吗?一旦您开始研究极端案例,您可能会发现这种抽象会崩溃。

值得注意的是,HashSet 实际上是作为HashMap 实现的,而不是相反。这纯粹是一个实现细节,但仍然很有趣。

entrySet() 存在的主要原因是为了简化遍历,因此您不必遍历键然后查找键。不要将其作为 Map 应该是条目的 Set 的初步证据(恕我直言)。

关于java - 为什么 Java Map 不扩展 Collection?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2651819/

相关文章:

java - field.setAccessible(false) 对非私有(private)字段的影响

PHP 代理对象

c++ - 实现者有细微差别的抽象类

java - 类型安全 : The expression of type List needs unchecked conversion to conform to Collection<? 扩展对​​象>

Java ArrayList 不允许我从外部构造函数添加

java - 由于静态初始化而调用的构造函数

java - 如何使用 Java Stream API 查找字符串中重复出现的子字符串

java - 什么是 Java 中好的可调整大小、随机访问、高效的字节 vector 类?

Java - 为什么我会收到 UnknownFormatConversionException?

c++ - 一个已经存在的注册表类的包装器类是一个好方法吗?