2009-05-03 48 views
2

在Java中,AbstractCollection类中的containsAll和retainAll明确指出基数不受尊重,换句话说,每一边有多少个值实例并不重要。由于标准库中的所有Java集合都扩展了AbstractCollection,因此假定它们都工作相同。在Collection接口地址基数中是否包含All()和retainAll()?

但是,Collection接口中这些方法的文档没有说明什么。是否应该从AbstractCollection中推断出来,还是为了让用户定义具有不同工作效果的集合而没有明确说明?

例如,apache集合中的Bag明确声明它确实尊重基数,并声称它违反了集合版本的合约(即使它不是真的)。

那么,这些操作在Collection中的语义是什么,而不是AbstractCollection中的?

编辑:那些想知道为什么我会在意的人,这是因为我的博士学位的一部分。工作我证明开发人员不希望Apache中的一致性违规,但我想了解为什么Collection接口留下如此含糊不清。

回答

2

的containsAll的javadoc(中集)说:

返回:如果此集合 包含所有 指定集合中元素的

和的retainAll(在集合):

仅保留那些包含在 指定集合(可选 操作)在此 集合的元素。换句话说,从该集合中删除 所有 元素,这些元素不包含在 指定集合中。

我读containsAll的合同意味着调用a.containsAll(二)将返回true,当且仅当,对于B中的每个元素调用贝伦a.contains(贝伦)将返回true。我也会认为a.containsAll(someEmptyCollection)也会返回true。当你的国家的Javadoc多类AbstractCollection明确说明这一点:

此实现迭代的 指定的集合,检查由迭代中 又将回到看它是否包含在此 集合中的每个元素 。如果所有元素均如此 包含true返回,否则 为false。

我同意集合for containsAll的联系人应该更加明确以避免任何可能的混淆。(并且阅读AbstractCollection的javadocs不应该是必需的,以确认对Collection的理解)

我不会在调用retainAll后对重复元素的数量做出假设。 Collection中所陈述的合同(通过我的阅读)并不意味着如何处理两个集合中的重复。基于在a.retainAll集合多种可能的结果我的的retainAll阅读(二),都是合理的:

  1. 结果包含在既有的至少一个拷贝和b的每个元素的1
  2. 结果包含除了那些不在b中的每个元素(包括重复),除了那些不在b中的元素之外的结果包含1和在a中的每个元素中找到的副本的数量之间的某处之外,除了那些不在b中的元素之外。 我本可以预期#1或#2,但会假设三者中的任何一个都是基于合同合法的。

的类AbstractCollection的javadoc证实,它使用#2:如果它包含在指定

此实现迭代该 收集,检查每个元素 通过依次迭代器返回到 看 集合。如果它不是那么遏制, 它是从这个集合中删除与 迭代器的remove方法

虽然,因为这不是我的原Collection接口的合同的阅读,我不一定会承担收集行为一般是这样。

也许您应该考虑在完成后向JavaDoc提交建议的更新。至于'为什么Collection接口仍然如此模糊' - 我严重怀疑这是故意做的 - 可能只是在API的这部分被编写时没有给予其应有的优先权。

0

我不认为集合定义这种方式或其他,但它只是成为某种惯例遵循的行为类AbstractCollection,例如google-collections做:看their Multiset documentation(多集就是他们所谓的袋)

+0

问题是该约定可能会导致界面的误解。例如,Apache中的Bag文档说这是在Collection中声明的,尽管它在AbstractCollection中声明。从执行的典型行为中推断界面合同通常不是一个好主意...... – Uri 2009-05-03 05:41:36

+0

我完全同意你的看法。这是事实上的,而不是法律上的合同。所以我认为以不同的方式实现一个集合是可以的,但是强调了Javadoc的不同之处,就像Apache Collections一样。 – Yardena 2009-05-03 07:18:33

相关问题