文档

Java™ 教程-Java Tutorials 中文版
实现
Trail: Collections

课程:实现

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

通用实现总结在 下表 中。

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

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

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

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

如果需要线程安全集合,则 Wrapper Implementations 部分中描述的同步包装器允许将 any (任何) 集合转换为同步集合。因此,同步对于通用实现是可选的,而对于遗留实现是必需的。此外,java.util.concurrent 包提供了 BlockingQueue 接口的并发实现,它继承了 Queue ,以及提供 ConcurrentMap 接口,继承 Map。这些实现提供了比仅仅同步实现更高的并发性。

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

以下部分简要讨论了实现。使用诸如 constant-time (常量时间)loglinear (线性)n log(n)quadratic (二次的) 等词来描述实现的性能,指的是执行操作的时间复杂度的渐近上界。所有这一切都是绕口的,如果你不知道它意味着什么并不重要。如果你有兴趣了解更多信息,请参阅任何优秀的算法教科书。需要记住的一点是,这种性能指标有其局限性。有时,名义上较慢的实现可能会更快。如有疑问,请测量性能!


Previous page: Previous Lesson
Next page: Set Implementations