19

Collection 接口有多种方法。List 接口扩展了 Collection 接口。它声明了与 Collection 接口相同的方法?为什么会这样?

例如

interface Collection extends Iterable
{
     public abstract int size();
 public abstract boolean isEmpty();
 public abstract boolean contains(java.lang.Object);
 public abstract java.util.Iterator<E> iterator();
 public abstract java.lang.Object[] toArray();
 public abstract <T extends java/lang/Object> T[] toArray(T[]);
 public abstract boolean add(E);
 public abstract boolean remove(java.lang.Object);
 public abstract boolean containsAll(java.util.Collection<?>);
 public abstract boolean addAll(java.util.Collection<? extends E>);
 public abstract boolean removeAll(java.util.Collection<?>);
 public abstract boolean retainAll(java.util.Collection<?>);
 public abstract void clear();
 public abstract boolean equals(java.lang.Object);
 public abstract int hashCode();
}

List 接口中也存在相同的方法:

public interface List extends Collection
{
 public abstract int size();
 public abstract boolean isEmpty();
 public abstract boolean contains(java.lang.Object);
 public abstract java.util.Iterator<E> iterator();
 public abstract java.lang.Object[] toArray();
 public abstract <T extends java/lang/Object> T[] toArray(T[]);
 public abstract boolean add(E);
 public abstract boolean remove(java.lang.Object);
 public abstract boolean containsAll(java.util.Collection<?>);
 public abstract boolean addAll(java.util.Collection<? extends E>);
 public abstract boolean removeAll(java.util.Collection<?>);
 public abstract boolean retainAll(java.util.Collection<?>);
 public abstract void clear();
 public abstract boolean equals(java.lang.Object);
 public abstract int hashCode();
}

如果已经在扩展 Collection 接口,是否需要在 List 中再次编写这些方法?

4

8 回答 8

29

它们被重新编写,以便可以记录它们,以便指定 List 如何与 Collection 接口中指定的合同相比改进这些方法的合同。

例如,add()方法 inList被记录以指定将元素添加到列表的末尾。这不能在 Collection 中指定,因为 Collection 没有开始和结束。

于 2013-08-10T10:23:14.883 回答
14

随着继承层次结构的向下移动,JavaDoc 和 API 契约会有所改变/或变得更加具体。

List 重新声明了这些方法并为它们提供了更具体的 JavaDoc。

于 2013-08-10T10:23:26.393 回答
6

只是为了方便。

文档中提到的相同

List 接口对迭代器、add、remove、equals 和 hashCode 方法的合约添加了超出 Collection 接口中指定的附加规定。为方便起见,此处还包括其他继承方法的声明

于 2013-08-10T10:24:11.170 回答
3

Collection<T>只是一组项目。就其本身而言,它没有比持有对其成员的许多项目的引用更多的要求。

在基本的 java api 中有两种主要类型的集合:List<T>Set<T>.

List<T>有额外的要求来维护其所有项目的特定顺序(插入顺序、排序顺序......)。因此,如果您请求项目 N,列表将始终为 N 返回相同的项目。

Set<T>不对订单提供任何保证,但对商品的唯一性提供保证。一个项目 A 不能两次添加到一个集合中,或者在一个集合中只会出现一次。

您应该熟悉“标记”界面的实践。Serializable就是其中之一,通常是谈论这个的基本例子。并且List<T>这样Set<T>声明,它们将集合标记为一个或另一个,以便通知程序员他们可以从收到的集合中期望的行为。

请参阅“Effective Java”的第 37 条(第 6 章),以很好地解释这比使用注解更好。

还有一个事实myCollection instanceof MyInterface是比myCollection.getClass().isAnnotationPresent(MyAnnotation.class)or更快myCollection.getClass().getAnnotation(MyAnnotation.class) != null

于 2013-08-10T11:18:25.503 回答
2

集合只是项目的集合

一个列表,除了保存项目列表之外,还向其中添加有关内容序列的信息。

当您将项目添加到集合时,您只是在添加它。将项目添加到 List 时,可以在位置n处添加

当您从集合中删除一个项目时,您只是将其删除。当你从 List 中移除一个项目时,你可以在位置n移除

当您想从集合中获取项目时,您必须进行迭代。当你想从 List 中获取一个项目时,你可以在位置n

于 2013-08-10T10:41:47.243 回答
2

方法上的签名toArray表明您是从编译.class文件中提取的。类文件格式指定该文件.class不重复从超级接口继承的方法,因此我怀疑您用来获取这些方法的任何工具都在向您显示复合视图;这些方法实际上并不存在于List.

于 2013-08-10T10:27:10.407 回答
1

这主要是因为他们这样使用的文档目的。

例如

Collection#retainAll 

仅保留此集合中包含在指定集合中的元素(可选操作)。

List#retainAll

仅保留此列表中包含在指定集合中的元素(可选操作)。

仅出于 java doc 的目的,他们就这样使用了。但是某些方法的行为本身发生了变化。

For ex.add,remove

方法删除

In List, Removes the first occurrence of the specified element from this list, if it is present (optional operation).

In Collection , Removes a single instance of the specified element from this collection, if it is present (optional operation).

通过 Java 文档,他们清楚地表明 List 实现是有序的。

于 2014-08-15T13:01:59.367 回答
1

首先接口List继承了所有Collection方法,所以Collection接口中存在的所有方法也会存在List接口中,但是List接口有额外的方法,(自行检查)描述了list的行为

于 2013-12-23T01:16:34.023 回答