原文地址:Collections Framework Overview
介绍
Java
平台中有一个集合框架collections framework
。集合表示一组对象集的对象(例如经典的Vector
类)。集合框架用来表示和操作集合的统一架构,可以抛开实现细节来操作集合。集合框架主要的有点如下所示:
- 减少编程工作量 :提供了数据结构和算法,无需我们自己编写实现。
- 提高性能:提供了高性能的数据结构与算法的实现,因为各个实现之间是可以相互转换的,所以可以通过转换实现来调整程序。
- 提供不相关API之间互通性:建立一种通用的语言来回传递集合。
- 减少学习API成本:只需要关注几个指定的
API
。 - 减少设计与实现API的成本:不需要使用者实现指定的
API
。 - 重用性强: 为集合和算法提供了标准的接口。
集合框架包括:
- 集合接口。提供了不同类型的集合接口,例如
sets, lists,
和maps
。这些接口作为集合框架的基础。 - 通用实现类。 提供了集合接口的主要通用实现。
- 传统实现类。 改进早期版本的集合类
Vector
和Hashtable
来实现集合接口。 - 专用实现类。 针对特殊场景的实现,这些实现显示出非标准的性能特征、使用限定或行为。
- 快速实现类。 集合接口的高性能的“微实现”。
- 抽象实现类。 集合接口的部分实现抽象出来方便与其他自定义的实现复用。
- 算法。 集合实现某种功能的静态方法,如:
list
排序。 - 基础服务。 提供为集合接口必要支持的接口。
- 数组工具。 提供一些基础数组和引用数组的使用方法。严格的说,不算是集合框架的一部分。这次会将这些方法与集合框架同时加入
Java
平台,并同时依赖一些相同的基础架构。
集合接口
集合接口被分为2组,java.util.Collection
是最为基础的接口,有如下子类:
java.util.Set
java.util.SortedSet
java.util.NavigableSet
java.util.Queue
java.util.concurrent.BlockingQueue
java.util.concurrent.TransferQueue
java.util.Deque
java.util.concurrent.BlockingDeque
另外一些集合接口基于java.util.Map
类而且并非真正意义上的集合。但是这些接口包含集合视图的操作,可以将其转换为集合。以下是继承与Map
的子类:
java.util.SortedMap
java.util.NavigableMap
java.util.concurrent.ConcurrentMap
java.util.concurrent.ConcurrentNavigableMap
在集合接口中大多数可重写的方法会被标记成optional
。实现类允许不执行这些方法,如果尝试执行会抛出异常(UnsupportedOperationException
)。每个实现类的文档必须说明支持哪些可选操作。以下介绍几种说明来帮助理解此规范:
- 集合中不支持可修改的操作(例如
add
、remove
和clear
)被称为不可修改的(unmodifiable
)。集合不是unmodifiable
是可以被修改的。 - 集合要确保集合对象不会改变的集合被称为不可变的(
immutable
)。集合不是immutable
是可以改变的。 lists
保证其元素个数保持不变,即使元素被改变也被称为固定大小(fixed-size
)。不是fixed-size
的lists
大小可以改变。- 支持快速(通常是固定时间)索引元素访问的
lists
被为随机访问list
。被随机访问的标记的lists
表明其可以被随机访问。这允许一些通用的算法来改变其的行为,适用于随机或顺序访问的lists
,来提供良好的性能。
某些实现限定只能存储特定的元素(或者Map
中的一种,key和values)。可能元素的限制可能有:
- 特定类型
- 非null类型
- 遵循一些特定的述语的
尝试添加一个不符合某实现类限制的元素, 会导致运行时异常, 通常是 ClassCastException
, IllegalArgumentException
或者 NullPointerException
。 尝试删除或者查询一个不符合某实现类限制的元素, 也会导致抛异常。但是也有一些有限制的集合允许这样做.
集合实现
典型的实现类的名称形式通常来源于其接口<Implementation-style><Interface>
。以下表格是集合常用的实现类的概览:
这些通用实现类支持集合接口中所有的optional
操作,对于所包含的元素也没有限制。他们是不同步的,但是如果集合类包含静态元素被称为同步包装器(synchronization wrappers
)将会被用来给这些不同步的实现类做同步拓展。所有的新的实现类都有快速失败迭代器,用来发现无效的同步修改并快速彻底舍弃(而不是不规律的行为)。
AbstractCollection
, AbstractSet
, AbstractList
, AbstractSequentialList
和 AbstractMap
这些抽象类提供核心集合接口的基础实现,减少了他们现实的成本。这些类API
文档明确描述了每一个方法是如何实现的,以便实现的人知道哪些方法必须被重写,API
文档也给出特定实现中每种基本操作的性能表现。
并发集合
应用在多线程环境下使用集合要加以小心。通常,这也被成为并发编程。Java
平台提供了并发编程的拓展,详细见Java Concurrency Utilities
。
集合如此频繁被使用,是因为在APIs
中一些友好并发的接口和集合的实现。这些类超出了之前讨论的并发包装器,并频繁应用于并发编程中。
可用的支持并发的接口有:
BlockingQueue
TransferQueue
BlockingDeque
ConcurrentMap
ConcurrentNavigableMap
以下是支持并发的实现类,可以在其文档中查看这些实现的并发使用方法:
LinkedBlockingQueue
ArrayBlockingQueue
PriorityBlockingQueue
DelayQueue
SynchronousQueue
LinkedBlockingDeque
LinkedTransferQueue
CopyOnWriteArrayList
CopyOnWriteArraySet
ConcurrentSkipListSet
ConcurrentHashMap
ConcurrentSkipListMap
设计目标
主要的设计目标创造出一套轻量级、重概念的API
。至关重要的是新的功要与现有的Java
程序看起来并无太多的差异。必须要拓展当前的服务,而不是设法替换它。同时,新API
需要有足够的能力来保证提供之前描述的优点。
为了使得核心接口的数量少,接口并没有试图去捕捉一些细微的差别,形如:集合对象的可变性、集合元素的可修改性、集合长度的可变性。相反,在核心接口中这些特性明确是可选的,允许在实现中抛出UnsupportedOperationException
异常来表明其不支持某个指定可选方法。集合实现类必须在文档中表明每个实现类支持哪些操作。
为了保持每个核心接口中的方法足够少,一个接口包含一个方法必须符合如下条件之一:
- 这是一个重要且基础的操作:就被合理定义而言,这应该是一个基本操作。
- 必须有一个令人信服的性能原因才能使得一个重要的实现类去重写它。
至关重要的是集合所有合理的表示需要有好的相互操作性。这包括数组,除非改变语言,否则不可能直接通过数组来实现集合接口。因此,集合框架包含了可以将集合转换数组的方法,以及arrays
和maps
被视为集合。