本篇主要介绍一下集中集合接口的实现:
- 通用目的实现 是最常用的实现,专门为日常使用而设计,请看下表通用目的的实现中的总结
- 特殊用途实现 专为特殊情况下使用而设计,并显示非标准性能特性,使用限制和表现
-
并发实现 被设为为支持高并发,通常以牺牲单线程下的性能为代价。这些实现在
java.util.concurrent
包下面 - **包装实现 **封装器实现与其它类型的实现(通常是通用实现)结合使用,以提供增加的或限制的功能
- 方便实现 是一个比较迷你的实现,通常通过静态工厂方法,为特殊集合(比如单例集合)的通用实现提供便利和搞笑的替代选择
- 抽象实现
通用实现的总结如下表:
接口 | hash table的实现 | 可调大小的数组实现 | 树的实现 | 链表的实现 | hash table & linked list的实现 |
---|---|---|---|---|---|
Set | HashSet | TreeSet | LinkedHashSet | ||
List | ArrayList | LinkedList | |||
Queue | |||||
Deque | ArrayDeque | LinkedList | |||
Map | HashMap | TreeMap | LinkedHashMap |
这些通用实现的共同点:
- 每一个通用的实现都提供接口中包括的可选操作。
- 都允许把
null
作为元素,或者作为键,或者作为值。 - 都不是同步的(线程不安全),
- 都提供快速失败的迭代器,其在迭代期间检测非法的并发修改并且快速失败。而不是冒着风险去在不确定的未来和不确定的行为。
- 都是可以序列化的并支持公共的拷贝方法。
事实上,这些实现是不同步的,代表了与过去的分离:遗留集合Vector和Hashtable是同步的。采用本方法是因为当同步没有益处时经常使用集合。这样的用途包括单线程使用,只读使用和作为自己同步的更大数据对象的一部分。一般来说,这是好的API设计实践,不让用户支付他们不使用的功能。此外,不必要的同步可能在某些情况下导致死锁。
如果需要线程安全的集合,同步的封装器(
synchronization wrappers
),允许任何的集合被转换到对应的同步集合。所以同步对于通用目的的实现类来说是可选的。但对于遗留的Vector
和HashTable
是必选的。此外,java.util.concurrent
包提供了扩展了Queue
的BlockingQueue
接口以扩展了Map
的ConcurrentMap
接口的并发实现类。这些实现比单纯的同步的实现有这更高的并发性能; 通常情况下,你应该考虑的是接口,而不是实现。这就是本节中没有编程示例的原因。大多数情况下,实现仅影响性能,
正如你看到的,java集合框架提供了几个通用的实现关于接口 Set
List
Map
。
显然,大多数情况下Hashset
ArrayList
HashMap
这几个实现使用的情况最多。
SortedMap
和SortedSet
没有出现在上表中,因为这两个接口都有一个对应的实现TreeMap
和TreeSet
对应于Map
和Set
接口。
对于接口Queue
,有两个通用的实现,但意义不同
-
LinkedList
这也是一个List
的实现,是一个FIFO队列,即先进先出。 -
PriorityQueue
优先级队列根据其值对其元素排序。
以上部分简要讨论了实现。使用诸如常数时间,对数,线性,n log(n)和二次函数的词来描述执行操作的时间复杂度的渐近上界来描述实现的性能。如果你不知道这是什么意义,这并不重要。如果你有兴趣了解更多,请参考任何好的算法教科书。需要记住的一点是,这种性能指标有其局限性。有时,名义上较慢的实现可能更快。当有疑问时,测量性能!