文档

Java™教程
隐藏目录
实现
路径: 集合类

课程: 实现

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

通用实现在下表中进行了总结。

通用实现
接口 哈希表实现 可调整大小的数组实现 树实现 链表实现 哈希表 + 链表实现
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 元素、键和值。没有进行同步(线程安全)。所有都具有快速失败的迭代器,在迭代过程中检测到非法并发修改时会快速、干净地失败,而不会冒着在未来的某个不确定的时间出现任意、非确定性行为的风险。所有都是可序列化的,并且都支持公共的 clone 方法。

这些实现不进行同步的事实代表了与过去的断裂:旧的集合 VectorHashtable 是同步的。现在采取的方法是因为集合在同步时经常没有任何好处。这些用途包括单线程使用、只读使用以及作为一个更大数据对象的一部分,该对象执行自己的同步。一般来说,好的API设计实践是不要让用户为他们不使用的功能付费。此外,不必要的同步可能会在某些情况下导致死锁。

如果您需要线程安全的集合,可以使用在包装器实现部分中介绍的同步包装器将任何集合转换为同步集合。因此,对于通用实现,同步是可选的,而对于旧实现则是强制的。此外,java.util.concurrent包提供了BlockingQueue接口的并发实现,该接口扩展了Queue,以及ConcurrentMap接口的并发实现,该接口扩展了Map。这些实现比纯粹的同步实现提供了更高的并发性。

通常情况下,您应该考虑接口,而不是实现。这就是为什么本节中没有编程示例的原因。在大多数情况下,实现的选择只影响性能。如接口部分所述,首选的风格是在创建Collection时选择一个实现,并将新的集合立即分配给相应接口类型的变量(或将集合传递给期望接口类型参数的方法)。通过这种方式,程序不会依赖于给定实现中的任何新增方法,使程序员可以自由地根据性能问题或行为细节的需要随时更改实现。

接下来的章节简要讨论了这些实现。对于实现的性能,使用常数时间对数线性n log(n)平方等词来描述操作的渐近上限时间复杂度。这些内容可能有些晦涩,如果您不了解它的含义也没关系。如果您对此有兴趣,可以参考任何一本优秀的算法教材。需要记住的一点是,这种性能指标有其局限性。有时,名义上更慢的实现可能更快。如果有疑问,可以测量性能!


上一页:上一课程
下一页:集合实现