集合(Collection)和集(Set)是相同的吗?

4
我有一个关于Java中这两个接口的问题。 Set继承自Collection,但是没有添加任何内容。它们完全相同。 我是否漏掉了什么?
6个回答

8

集合(Set)不允许重复项。

这是一种语义上的区别,而不是语法上的区别。


+1:对于接口来说,规范和方法定义一样重要。 - Joachim Sauer
所以我不明白,为什么需要Set<E>。从面向对象的角度来看感觉不对。 - Yaron Levi
将同一个对象分别插入Set和Collection中两次。 - Vito De Tullio

6

一个集合表示一组对象,称为其元素。有些集合允许重复的元素,而另一些则不允许。 有些是有序的,而其他则是无序的。

一个不包含重复元素的集合。 更正式地说,集合不包含任何一对元素 e1e2,使得 e1.equals(e2),并且最多只有一个 null 元素。正如其名称所暗示的那样,该接口模拟了数学中的集合抽象。

这应该澄清了 Set 和(更通用的接口)Collection 之间的区别。


5

好问题。我想明确为概念Set设立接口,与概念Collection相比的主要目的是实际上正式地区分这些概念。假设您正在编写一个方法

void x(Collection<?> c);

如果你在写作时,你想要获取的参数与其他人不同,那么你可能需要进行一些调整。

void x(Set<?> s);

第二种方法期望包含每个元素最多一次的Collections(即Sets)。这与第一种方法有很大的语义差异,第一种方法不关心它接收到的是SetsLists还是任何其他类型的Collection
如果仔细观察Set方法的Javadoc,也会发现其不同之处,明确显示了在讨论CollectionSet时涉及的不同概念。

我还是不明白。如果Set<E>仅仅通过它的名称暗示我们有一个没有多个对象的集合,并且没有通过任何代码更改来强制执行它,那么我们为什么需要它呢?如果我正在实现集合,我可以只使用一个名称来暗示这种行为。 - Yaron Levi
1
正是出于我之前提到的原因(以及其他人在这里提到的原因)。因为这样,我可以正式地期望我的方法中有一个Set参数,而不仅仅是一个普通的Collection。这是其中许多原因之一。 - Lukas Eder
我正在关注这个帖子。如果您能引用一个可行的例子,以便日后参考,将不胜感激。 - Deepak
1
嗯,举个例子...好的,请查看java.util.Map<K, V>接口。例如,它有这两种方法:Set<K> keySet()Collection<V> values()。众所周知,每个键只能在Map中包含一次,并且键的顺序是不相关的。因此,SetCollection更好,因为它正式传达了这一事实。对于values()来说情况就不同了。我们不知道一个值是否可以在映射中包含多次,而且顺序也是不相关的。因此,最好的选择是Collection - Lukas Eder

2

集合是一个更通用的接口,包括列表、队列、集合等等。

请看这里的“所有已知子接口”部分(链接)


0

一切都在文档中:

Set - 一个不包含重复元素的集合。更正式地说,集合不包含任何满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多只能有一个空元素。如其名称所示,该接口模拟了数学集合抽象。

Collection - 集合层次结构中的根接口。集合代表着一组对象,称为其元素。某些集合允许重复元素,而其他集合则不允许。某些集合是有序的,而其他集合则是无序的。SDK 不直接提供该接口的任何实现:它提供了更具体的子接口(如 Set 和 List)的实现。这个接口通常用于传递集合并在需要最大广泛性的情况下操作它们。

仅用于区分实现和未来使用。

这源自于集合理论和字典。

Collection - 被收集的东西;在一个位置累积的一组对象或一定数量的材料,特别是出于某种目的或某个过程的结果

Set - 是一组不同对象的集合


0
此外,Set 文档定义了关于 .equals 的契约,其中说到“只有其他 Set 可以等于此 Set”。如果我们无法通过它们的类型(使用 instanceof)识别其他 Set,则无法实现此功能。
如果仅针对 equals(),则可以为 Collection 设计一个 allowsDuplicates() 方法。但通常情况下,API 希望表达“请不要给我重复项”或“我保证此项不包含重复项”的意思,在 Java 中没有一种方法能在方法声明中说出“请只提供其 allowsDuplicates() 方法返回 false 的集合”。因此需要添加该类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接