【Java文档】Java集合框架概述
文章目录
本文档主要是翻译的Collections Framework Overview,基于Java8。
概述
集合框架是表示和操作集合的统一体系结构,使它们能够独立于表示的细节进行操作。它在提高性能的同时减少了编程工作。它支持不相关api之间的相互操作,减少了设计和学习新api的工作量,并促进软件重用。该框架基于十几个集合接口。它包括这些接口的实现和操作它们的算法。
集合框架的主要优势在于:
- 通过提供数据结构和算法来减少编程工作量,这样就不必自己编写了。
- 通过提供高性能的数据结构和算法实现来提高性能。因为每个接口的各种实现是可互换的,所以可以通过选择不同实现来调整程序。
- 通过建立一种公共语言用于来回传递集合,从而提供不相关API之间的互操作性。
- 减少学习API所需的工作量,只需要学习几个特定集合API。
- 减少了设计和实现API所需的工作量,因为不需要生成特殊集合API。
- 通过为集合和算法提供一个标准接口来操纵它们,从而促进软件重用。
集合框架主要包括:
- 集合接口。表示不同类型的集合,例如集合、列表和映射。这些接口构成了框架的基础。
- 通用实现。集合接口的主要实现。
- 遗留实现。早期版本的集合类
Vector
和Hashtable
经过了改造,实现了集合接口。 - 特殊目的实现。为在特殊情况下使用而设计的实现。这些实现表现出非标准的性能特征、使用限制或行为。
- 并发实现。为高并发使用而设计的实现。
- 包装器实现。将同步等功能添加到其他实现中。
- 快捷实现。集合接口的高性能“迷你实现”。
- 抽象实现。集合接口的部分实现,以便于自定义实现。
- 算法。对集合执行功能函数的静态方法,例如对列表排序。
- 基础设施。为集合接口提供基本支持的接口。
- 数组实用程序。基本类型数组和引用对象的实用函数。严格来说,它不是集合框架的一部分,这个特性是与集合框架同时添加到Java平台的,并且依赖于一些相同的基础设施。
集合接口
集合接口分为两组。最基本的接口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
集合接口中的许多修改方法都被标记为可选。允许实现类不执行这些操作中的一个或多个,如果尝试执行这些操作,将引发运行时异常(UnsupportedOperationException
)。每个实现的文档必须指定支持哪些可选操作。本规范中引入了几个术语:
- 不可修改:不支持修改操作(如
add
、remove
和clear
)的集合称为不可修改。非不可修改的集合是可修改的。 - 不可变:额外保证
Collection
对象中任何更改都不可见的集合被称为不可变的。非不可变的集合是可变的。 - 即使元素可以改变,但能保证其大小保持不变的列表称为固定大小列表。非固定大小的列表称为可变大小的列表。
- 固定大小:即使元素可以改变,但能保证其大小保持不变的列表称为固定大小列表。非固定大小的列表称为可变大小的列表。
- 随机访问列表:支持快速(通常是恒定时间)索引元素访问的列表称为随机访问列表。不支持快速索引元素访问的列表称为顺序访问列表。列表通过
RandomAccess
标记接口来标识其支持随机访问。这使得通用算法能够改变它们的行为,从而在应用于随机或顺序访问列表时提供良好的性能。
一些实现限制了可以存储什么元素(在Map中是键和值)。可能的限制包括:
- 属于某一类型
- 非空
- 遵守一些断言
试图添加违反实现类限制的元素会导致运行时异常,通常是ClassCastException
、IllegalArgumentException
或NullPointerException
。试图删除或测试违反实现类限制的元素是否存在可能也会导致异常。一些有限制的集合允许这种用法。
集合实现类
实现集合接口的类通常具有<实现方式><接口名>形式的名称。下表总结了通用实现:
接口 | Hash表 | 可变数组 | 平衡树 | 链式集合 | Hash表 + 链式集合 |
---|---|---|---|---|---|
Set |
HashSet |
TreeSet |
LinkedHashSet |
||
List |
ArrayList |
LinkedList |
|||
Deque |
ArrayDeque |
LinkedList |
|||
Map |
HashMap |
TreeMap |
LinkedHashMap |
通用实现支持集合接口中的所有可选操作,并且对它们可能包含的元素没有限制。它们是不同步的,但Collections
类包含称为“同步包装器”的静态工厂,可用于向许多不同步的集合添加同步机制。所有新的实现都有快速失败的迭代器,它可以检测到无效的并发修改,并且快速而干净地失败(而不是行为不稳定)。
AbstractCollection
、AbstractSet
、AbstractList
、AbstractSequentialList
和AbstractMap
类提供了核心集合接口的基本实现,以最小化实现这些接口所需的工作量。这些类的API文档精确地描述了每个方法是如何实现的,以便实现者知道在给定的特定实现的基本操作性能的情况下,哪些方法必须被重写。
并发集合
使用来自多个线程的集合的应用程序必须小心编程。一般来说,这被称为并发编程。Java平台包括对并发编程的广泛支持。有关详细信息,请参见Java并发实用程序。
API中包含了各种并发友好的接口和集合的实现,这些集合的使用非常频繁。这些类型超越了前面讨论的同步包装器,提供了并发编程中经常需要的特性。
有如下并发相关接口可用:
有如下并发相关实现类可用。有关这些实现的正确用法,请参阅API文档。
- LinkedBlockingQueue
- ArrayBlockingQueue
- PriorityBlockingQueue
- DelayQueue
- SynchronousQueue
- LinkedBlockingDeque
- LinkedTransferQueue
- CopyOnWriteArrayList
- CopyOnWriteArraySet
- ConcurrentSkipListSet
- ConcurrentHashMap
- ConcurrentSkipListMap
设计目标
主要的设计目标是创造一个小体积的API,更重要的是“概念重”;它必须扩充现有设施,而不是取代它们。同时,新的API必须足够强大,以提供前面描述的所有优点。
为了使核心接口的数量保持较小,接口不会试图捕捉诸如可变性、可修改性和可调整大小等细微差别。相反,核心接口中的某些调用是可选的,使实现能够抛出UnsupportedOperationException
以标识出它们不支持指定的可选操作。集合实现者必须清楚地记录实现支持哪些可选操作。
为了使每个核心接口中的方法数保持较小,接口仅在以下任一情况下包含方法:
- 这是一个真正的基本操作:一个可以合理定义其他操作的基本操作
- 之所以一些重要实现要重写该方法是由于性能方面的原因
至关重要的是,集合的所有合理表示都能很好地相互操作。这包括数组,在不更改语言的情况下,无法使其直接实现集合接口。因此,该框架包括使集合能够移动到数组中、将数组视为集合以及将映射视为集合的方法。
文章作者 hongmao
上次更新 2021-06-17