为了账号安全,请及时绑定邮箱和手机立即绑定

Java Map为什么不扩展Collection?

Java Map为什么不扩展Collection?

qq_花开花谢_0 2019-10-06 13:25:20
事实Map<?,?>并非如此,这让我感到惊讶Collection<?>。我认为,如果这样声明,那将是很有意义的:public interface Map<K,V> extends Collection<Map.Entry<K,V>>毕竟,Map<K,V>是的集合Map.Entry<K,V>,不是吗?那么,为什么没有这样一个充分的理由实现它呢?感谢Cletus提供的最权威的答案,但是我仍然想知道为什么,如果您已经可以查看Map<K,V>as Set<Map.Entries<K,V>>(通过entrySet()),那么它不仅扩展了该接口。如果a Map是a Collection,元素是什么?唯一合理的答案是“键值对”确实interface Map<K,V> extends Set<Map.Entry<K,V>>会很棒!但这提供了非常有限的(且不是特别有用的)Map抽象。但是,如果是这种情况,那么为什么要entrySet由接口指定?它必须以某种方式有用(我认为很容易为该职位辩护!)。您不能问给定键映射到什么值,也不能在不知道给定键映射到什么值的情况下删除该键的条目。我并不是说这就是全部Map!它可以并且应该保留所有其他方法(entrySet现在除外,这是多余的)!
查看完整描述

3 回答

?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

我猜为什么是主观的。


在C#中,我认为可以Dictionary扩展或至少实现一个集合:


public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, 

    ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 

    IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback

在法鲁·斯玛塔克(Pharo Smalltak)中:


Collection subclass: #Set

Set subclass: #Dictionary

但是某些方法存在不对称性。例如,collect:将采用关联(相当于条目),而do:采用值。它们提供了另一种keysAndValuesDo:通过条目迭代字典的方法。Add:需要关联,但remove:已被“抑制”:


remove: anObject

self shouldNotImplement 

因此,它绝对可行,但会导致有关类层次结构的其他问题。


更好的是主观的。


查看完整回答
反对 回复 2019-10-06
?
MMTTMM

TA贡献1869条经验 获得超4个赞

尽管您已经获得了很多直接涵盖您问题的答案,但我认为退后一步,然后更笼统地看一下问题可能会很有用。也就是说,不要专门研究Java库是如何编写的,而是要研究编写Java库的原因。

这里的问题是,继承仅建模一种类型的公共性。如果您选择两个看起来都像“集合”的事物,则可能可以选择它们共同的8或10个事物。如果您选择另一对不同的“类似收藏的东西”,它们也会有8或10个共同点,但是它们与第一对将不会是相同的 8或10个东西。

如果你看一下有十几个不同的“集合式”的东西,实际上他们每个人都可能有这样的事情在普通8层或10的特性与至少一个其他-但如果你看看什么是跨共享的一个其中,您几乎一无所有。

在这种情况下,继承(尤其是单继承)建模效果不佳。在哪些是真正的集合与哪些不是真正的集合之间没有明确的分界线,但是,如果您想定义一个有意义的Collection类,则将其中的一些留在外面。如果只保留其中几个,则Collection类将只能提供相当稀疏的接口。如果您遗漏了更多内容,则可以为其提供更丰富的界面。

有些人还可以这样选择:“这种类型的集合支持操作X,但是您不能使用它,因为它是从定义X的基类派生的,但是尝试使用派生类的X会失败(例如,则引发异常)。

这仍然存在一个问题:几乎不管您遗漏了哪些内容,以及放了哪些内容,您都将不得不在哪些类和哪些类之间划清界限。无论您在哪条线上画线,都将在一些非常相似的事物之间留下清晰,人为的划分。


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 490 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信