为什么 Java Map 不扩展 Collection? [英] Why doesn't Java Map extend Collection?

查看:22
本文介绍了为什么 Java Map 不扩展 Collection?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很惊讶Map 不是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>>

毕竟,MapMap.Entry,对不对?

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?

感谢 Cletus 提供最权威的答案,但我仍然想知道为什么,如果您已经可以将 Map<K,V> 视为 Set(通过 entrySet()),它不只是扩展该接口.

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.

如果 MapCollection,那么元素是什么?唯一合理的答案是键值对"

If a Map is a Collection, what are the elements? The only reasonable answer is "Key-value pairs"

正是,interface Mapextends Set> 会很棒!

但这提供了一个非常有限(而且不是特别有用)的Map抽象.

but this provides a very limited (and not particularly useful) Map abstraction.

但是如果是这样,那么为什么接口指定了 entrySet 呢?它必须以某种方式有用(我认为很容易为那个立场争论!).

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.

我并不是说 Map 就是这样!它可以并且应该保留所有其他方法(除了entrySet,它现在是多余的)!

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)!

推荐答案

来自 Java 集合 API 设计常见问题:

这是设计使然.我们觉得映射不是集合和集合不是映射.因此,它Map 的扩展意义不大Collection 接口(或副反之).

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).

如果 Map 是一个集合,那么它是什么元素?唯一合理的答案是键值对",但是这个提供了非常有限的(而不是特别有用)地图抽象.你不能问给定的键值是多少映射到,也不能删除条目对于给定的密钥,不知道是什么它映射到的值.

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.

地图可以被视为集合(的键、值或对),以及这个事实体现在三个收藏"查看操作"在地图上(键集,entrySet 和值).同时,在原则上,可以将列表视为将索引映射到元素的映射,这有一个令人讨厌的特性从列表中删除一个元素更改与每个关联的密钥删除元素之前的元素.这就是为什么我们没有地图视图对列表的操作.

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.

更新:我认为这句话回答了大部分问题.值得强调的是,条目集合并不是特别有用的抽象.例如:

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:

Set<Map.Entry<String,String>>

允许:

set.add(entry("hello", "world"));
set.add(entry("hello", "world 2"));

(假设一个 entry() 方法创建了一个 Map.Entry 实例)

(assuming an entry() method that creates a Map.Entry instance)

Map 需要唯一的键,所以这会违反这一点.或者,如果您在条目的 Set 上强加唯一键,则它实际上并不是一般意义上的 Set.这是一个具有更多限制的 Set.

Maps require unique keys so this would violate this. Or if you impose unique keys on a Set of entries, it's not really a Set in the general sense. It's a Set with further restrictions.

可以说,您可以说 Map.Entryequals()/hashCode() 关系纯粹是关键,但即使如此问题.更重要的是,它真的增加了任何价值吗?一旦您开始查看极端情况,您可能会发现这种抽象性被打破了.

Arguably you could say the equals()/hashCode() relationship for Map.Entry was 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.

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

It's worth noting that the HashSet is actually implemented as a HashMap, not the other way around. This is purely an implementation detail but is interesting nonetheless.

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

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 a Map should be a Set of entries (imho).

这篇关于为什么 Java Map 不扩展 Collection?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆