2

集合实现

实现是用于存储集合的数据对象,它实现了接口部分中描述的接口,本节描述了以下几种实现:

  • 通用实现是最常用的实现,专为日常使用而设计。
  • 专用实现旨在用于特殊情况,并显示非标准性能特征、使用限制或行为。
  • 并发实现旨在支持高并发性,通常以单线程性能为代价,这些实现是java.util.concurrent包的一部分。
  • 包装器实现与其他类型的实现(通常是通用实现)结合使用,以提供增加的或受限制的功能。
  • 便利实现是通常通过静态工厂方法提供的小型实现,为特殊集合(例如,单例集)的通用实现提供方便、有效的替代方案。
  • 抽象实现是骨架实现,有助于构建自定义实现,一个高级主题,并不是特别困难,但相对较少的人需要这样做。

通用实现总结在下表中。

接口 哈希表实现 可调整大小的数组实现 树实现 链表实现 哈希表+链表实现
Set HashSet TreeSet LinkedHashSet
List ArrayList LinkedList
Queue
Deque ArrayDeque LinkedList
Map HashMap TreeMap LinkedHashMap

从表中可以看到,Java集合框架提供了SetListMap接口的几种通用实现。在每种情况下,其他所有条件都相同情况下,一个实现(HashSetArrayListHashMap)显然是用于大多数应用程序的一个实现。请注意,SortedSetSortedMap接口在表中没有列出,每个接口都有一个实现(TreeSetTreeMap),并在SetMap行中列出。有两种通用的Queue实现 — LinkedList(它也是List实现)和PriorityQueue(表中省略)。这两种实现提供了非常不同的语义:LinkedList提供FIFO语义,而PriorityQueue根据其值对元素进行排序。

每个通用实现都提供其接口中包含的所有可选操作,全部允许null元素、键和值,都不是同步的(线程安全的),它们都具有快速失败的迭代器,该迭代器可在迭代过程中检测到非法的并发修改,并且可以快速干净地失败,而不会在未来的不确定时间冒着任意、不确定的行为的风险。全部都是Serializable,并且都支持公共clone方法。

这些实现不同步的事实代表了与过去的突破:遗留集合VectorHashtable已同步,之所以采用本方法,是因为在同步没有好处的情况下经常使用集合。这些用途包括单线程使用、只读使用和作为实现自身同步的较大数据对象的一部分使用,通常,最好的API设计做法是不要让用户为不使用的功能付费,此外,在某些情况下,不必要的同步可能导致死锁。

如果需要线程安全的集合,则在“包装实现”部分中介绍的同步包装器允许将任何集合转换为同步集合。因此,对于通用实现来说,同步是可选的,而对于遗留实现来说,它是强制性的。此外,java.util.concurrent包提供了BlockingQueue接口(扩展Queue)和ConcurrentMap接口(扩展Map)的并发实现,这些实现比单纯的同步实现提供更高的并发性。

通常,你应该考虑接口,而不是实现,这就是为什么本节中没有编程示例的原因,在大多数情况下,实现的选择仅影响性能。首选样式,如“接口”部分所述,是在创建集合时选择一种实现,并立即将新集合分配给相应接口类型的变量(或将集合传递给需要接口类型参数的方法)。这样,程序就不会依赖于给定实现中添加的任何方法,从而使程序员在有性能问题或行为细节保证的任何时候都可以自由更改实现。

实现总结

实现是用于存储集合的数据对象,它们实现了接口课程中描述的接口。

Java集合框架提供了几个核心接口的通用实现:

  • 对于Set接口,HashSet是最常用的实现。
  • 对于List接口,ArrayList是最常用的实现。
  • 对于Map接口,HashMap是最常用的实现。
  • 对于Queue接口,LinkedList是最常用的实现。
  • 对于Deque接口,ArrayDeque是最常用的实现。

每个通用实现都提供其接口中包含的所有可选操作。

Java集合框架还为需要非标准性能、使用限制或其他异常行为的情况提供了几种特殊用途的实现。

java.util.concurrent包包含几个集合实现,这些实现是线程安全的,但不受单个排除锁的约束。

Collections类(与Collection接口相对)提供了对集合进行操作或返回集合的静态方法,这些方法称为包装实现。

最后,有几种便利的实现,当你不需要通用实现时,它们的效率可能会比通用实现高,可通过静态工厂方法提供便捷实现。


上一篇:聚合并行性

博弈
2.5k 声望1.5k 粉丝

态度决定一切