Collection

集合(Collection)是集合层次中的根接口, 它是一组称为元素的对象的组合. 有些集合允许重复元素, 有些则不允许. 有些是有序的, 有些是无序的. JDK没有提供该接口的任何直接实现: 它提供了更具体的子接口的实现, 如 SetList. 这个接口通常用于传递集合并在需要最大通用性的地方操作它们.

初见版本

1.2

定义

Interface Collection<E>

参数

参数类型参数名称参数描述
类型参数E集合元素的类型

说明

包 (Bags) 或多集(multisets 可能包含重复元素的无序集合)应当直接实现这个接口.

所有通用的 Collection 接口的实现类(这通常是通过自身一个子接口间接实现Collection的类)应该提供两个 "标准的" 构造函数:

  • 一个无参数构造函数, 它创建一个空集合
  • 一个构造函数具有单个类型为 Collection 的参数,它创建一个与它的参数相同的新集合. 该构造函数实际上允许用户复制任何集合来生成所需实现类型的等效集合.

但因为接口不能包方法实体, 所以这个"标准" 没有办法强制约定, 但是 Java 平台库中的所有通用 Collection 实现都遵守这个约定.

某些方法被指定为可选的. 即如果一个集合实现没有实现一个特定的操作, 它应该定义相应的方法来抛出UnsupportedOperationException. 这些方法在集合接口的方法规范中被标记为"可选操作".

合集框架接口中的许多方法都是根据 equals() 方法定义的. 例如 contains(Object o) 方法的规范说: "当且仅当该集合包含至少一个元素 e 且 (o==null ?e = = null: o.equals (e)). " 本规范不应被解释为暗示使用非 null 参数 o 调用 Collection.contains 会导致对任意元素 e 都调用 o.equals(e). 实现可以自由地实现优化, 从而避免 equals 调用, 比如, 通过首先比较两个元素的哈希码. Object.hashCode() 规范保证了哈希码不相等的两个对象无法相等. 更一般地说, 各种集合框架接口的实现可以自由地利用底层 Object 方法的指定行为, 只要实现者认为合适.

一些对集合执行递归遍历的集合操作可能会引起直接或间接包括其自身的集合实例实例异常的失败. 这包括 clone()equals()hashCode()toString() 方法. 实现可以选择性地处理自引用场景, 但是大多数当前的实现都没有这样做.

视图集合

大多数集合管理它们所包含的元素的存储. 而视图集合相反, 它本身并不存储元素, 而是依赖于一个支撑集合来存储实际的元素. 视图集合本身不能处理的操作被委托给后台集合. 视图集合的例子包括诸如由 Collections.checkedCollection, Collections.synchronizedCollection 以及 Collections.unmodifiableCollection 等方法返回的包装器集合. 视图集合的其他示例包括为相同元素提供不同表示形式的集合, 例如 List.subList() , NavigableSet.subSet() 或 Map.entrySet() 等方法所提供的集合. 对后台集合所做的任何更改都可以在视图集合中看到. 相应地, 对视图集合所做的任何更改(如果允许更改的话)也都将写入后台集合. 尽管从技术上讲 IteratorListIterator 不是集合, 但他们的实例也允许修改写入后台集合, 而且在某些情况下, 对后台集合的修改在迭代期间对迭代器是可见的.

不可变集合

集合接口的某些方法被认为是具有"破坏性的" 并被称为 "mutator" 方法,因为它们修改了它们所操作的集合中包含的对象组. 如果该集合实现不支持此操作, 可以让该方法抛出 UnsupportedOperationException. 如果调用对集合不产生影响的方法也应该(但不是必须)抛出 UnsupportedOperationException. 例如, 假设不支持添加操作的集合. 如果用一个空集合作为参数在这个集合上调用 addAll() 方法, 会发生什么? 添加零个元素没有任何效果, 因此允许这个集合不做任何事情, 也不抛出异常. 但是, 仍然建议在这种情况下无条件地抛出异常, 因为限定条件的情况下抛出异常可能会导致编程错误.

不可变集合是一个其所有的 mutator 方法(如上定义)都被指定为抛出 UnsupportedOperationException 的集合. 因此, 不能通过调用其上的任何方法来修改这样的集合. 要使集合正确不可变, 就要使得从它派生的任何视图集合也必须是不可变的. 例如, 如果一个 List 是不可变的, 那么 List.subList() 返回的 List 也是不可变的.

不可变的的集合不是必定不可变的. 如果包含的元素是可变的, 则整个集合显然是可变的, 即使它自身可能是不可修改的. 例如, 两个包含可变元素的不可修改列表. 如果元素发生了变异, 那么调用 list1.equals(list2) 的结果可能与一次调用不同, 即使两个列表都是不可变的. 但是, 如果一个不可变的集合包含所有元素都不可变, 则可以认为它的不可变是有效的.

不可变视图集合

不可变的视图集合是由不可变的集合所支撑的集合的视图. 它的 mutator 方法也会抛出 UnsupportedOperationException,而读取和查询方法被委托给支撑集合. 其效果是提供对支撑集合的只读访问. 这对于组件向用户提供对内部集合的读取访问权限很有用, 同时防止他们意外修改此类集合. 不可变视图集合的示例是由 Collections.unmodifiableCollection()Collections.unmodifiableList() 和相关方法返回的视图集合.

请注意, 对支撑集合的更改可能仍然是可能的, 如果发生更改, 变化也将通过不可变的视图展现. 因此, 不可变的视图集合不一定是不可变的. 但是, 如果不可变视图的支撑集合实际上是不可变的, 或者如果对支撑集合的唯一引用是通过不可变的视图, 则可以认为该视图实际上是不可变的.

该接口是 Java Collections Framework 的成员.

实现要求

默认方法实现(继承或以其他方式)不应用任何同步协议. 如果 Collection 实现具有特定的同步协议, 则它必须覆盖默认实现以应用该协议.

注意事项

虽然允许列表将自身包含为元素, 但要格外注意 equalshashCode 方法不再在此类列表上明确定义.

一些集合接口的实现对它们可能包含的元素有限制. 例如, 有些实现禁止 null 元素, 有些实现对元素的类型有限制. 尝试添加不合格的元素会引发未经检查的异常, 通常是 NullPointerExceptionClassCastException.

尝试查询不合格的元素的存在根据不同实现可能会引发异常也可能只是返回 false. 更一般地说, 如果对不合格的元素进行操作时, 则可能抛出异常也可能成功执行, 这取决于实现的选择, 这里的成功执行是指即便完成操作也不会将不合格的元素插入到列表中, 但执行完成了. 在此接口的规范中, 此类异常被标记为 "可选(optional)".

由每个集合决定自己的同步策略. 在实现没有更强的保证的情况下, 对正在被另一个线程改变的集合调用任何方法可能会导致未定义的行为; 这包括直接调用、将集合传递给可能执行调用的方法, 以及使用现有迭代器检查集合.