实现是用于存储集合的数据对象,它实现了接口部分中描述的接口,本节描述了以下几种实现:
java.util.concurrent
通用实现总结在下表中。
接口 | 哈希表实现 | 可调整大小的数组实现 | 树实现 | 链表实现 | 哈希表+链表实现 |
---|---|---|---|---|---|
Set | HashSet | TreeSet | LinkedHashSet | ||
List | ArrayList | LinkedList | |||
Queue | |||||
Deque | ArrayDeque | LinkedList | |||
Map | HashMap | TreeMap | LinkedHashMap |
从表中可以看到,Java集合框架提供了 Set
、 List
和 Map
接口的几种通用实现。在每种情况下,其他所有条件都相同情况下,一个实现( HashSet
、 ArrayList
和 HashMap
)显然是用于大多数应用程序的一个实现。请注意, SortedSet
和 SortedMap
接口在表中没有列出,每个接口都有一个实现( TreeSet
和 TreeMap
),并在 Set
和 Map
行中列出。有两种通用的 Queue
实现 — LinkedList
(它也是 List
实现)和 PriorityQueue
(表中省略)。这两种实现提供了非常不同的语义: LinkedList
提供FIFO语义,而 PriorityQueue
根据其值对元素进行排序。
每个通用实现都提供其接口中包含的所有可选操作,全部允许 null
元素、键和值,都不是同步的(线程安全的),它们都具有快速失败的迭代器,该迭代器可在迭代过程中检测到非法的并发修改,并且可以快速干净地失败,而不会在未来的不确定时间冒着任意、不确定的行为的风险。全部都是 Serializable
,并且都支持公共 clone
方法。
这些实现不同步的事实代表了与过去的突破:遗留集合 Vector
和 Hashtable
已同步,之所以采用本方法,是因为在同步没有好处的情况下经常使用集合。这些用途包括单线程使用、只读使用和作为实现自身同步的较大数据对象的一部分使用,通常,最好的API设计做法是不要让用户为不使用的功能付费,此外,在某些情况下,不必要的同步可能导致死锁。
如果需要线程安全的集合,则在“包装实现”部分中介绍的同步包装器允许将任何集合转换为同步集合。因此,对于通用实现来说,同步是可选的,而对于遗留实现来说,它是强制性的。此外, java.util.concurrent
包提供了 BlockingQueue
接口(扩展 Queue
)和 ConcurrentMap
接口(扩展 Map
)的并发实现,这些实现比单纯的同步实现提供更高的并发性。
通常,你应该考虑接口,而不是实现,这就是为什么本节中没有编程示例的原因,在大多数情况下,实现的选择仅影响性能。首选样式,如“接口”部分所述,是在创建集合时选择一种实现,并立即将新集合分配给相应接口类型的变量(或将集合传递给需要接口类型参数的方法)。这样,程序就不会依赖于给定实现中添加的任何方法,从而使程序员在有性能问题或行为细节保证的任何时候都可以自由更改实现。
上一篇:聚合并行性