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

    • 通用实现是最常用的实现,设计用于日常使用。它们概括在标题为“通用实现”的表中。
    • 专用实现旨在用于特殊情况,并显示非标准性能特征,使用限制或行为。
    • 并发实现旨在支持高并发性,通常以单线程性能为代价。这些实现是java.util.concurrent包的一部分。
    • 包装器实现与其他类型的实现(通常是通用实现)结合使用,以提供添加的功能或受限制的功能。
    • 便利实现是微型实现,通常通过静态工厂方法提供,这些微型实现为特殊集合(例如单例集)的通用实现提供了方便有效的替代方法。
    • 抽象实现是有助于实现自定义实现的基本实现——稍后在“ 自定义集合实现”部分中进行介绍。这是一个高级话题,并不是特别困难,但是很少有人需要这样做。

    下表总结了通用实现 。
    通用实现

    接口 哈希表实现 可调整大小的数组实现 树实现 链表实现 哈希表+链表实现
    Set HashSet TreeSet LinkedHashSet
    List ArrayList LinkedList
    Queue
    Deque ArrayDeque LinkedList
    Map HashMap TreeMap LinkedHashMap
    1. 你可以从表中看到,Java集合框架提供了 [`Set`](https://docs.oracle.com/javase/8/docs/api/java/util/Set.html), [`List`](https://docs.oracle.com/javase/8/docs/api/java/util/List.html)以及 [`Map`](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html)接口几种通用的实现。在每种情况下,所有其他条件都相同,一个实现— [`HashSet`](https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html), [`ArrayList`](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html)和 [`HashMap`](https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html)显然是用于大多数应用程序的实现。请注意,[`SortedSet`](https://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html)和 [`SortedMap`](https://docs.oracle.com/javase/8/docs/api/java/util/SortedMap.html)接口在表中没有行。每个接口都有一个实现 [(`TreeSet`](https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html)和 [`TreeMap`](https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html)),并在`Set`和`Map`行中列出。有两个通用`Queue`实现- [`LinkedList`](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html)(也是一个`List`实现)和 [`PriorityQueue`](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html)(表中省略了)。这两种实现提供了非常不同的语义:`LinkedList`提供FIFO语义,同时`PriorityQueue`根据其值对元素进行排序。<br /> 每个通用实现都提供其接口中包含的所有可选操作。全部允许的`null`元素,键和值。没有一个被同步(线程安全)。它们都具有_快速故障迭代器_,该_迭代器_可在迭代过程中检测到非法的并发修改,并且快速,干净地发生故障,而不会在未来的不确定时间内冒出任意,不确定的行为。全部都是`Serializable`,且支持公共`clone`方法。<br /> 这些实现不同步的事实表示与过去决裂:旧式集合`Vector`和`Hashtable`已同步。之所以采用本方法,是因为在同步没有好处时,经常使用集合。这样的用途包括单线程用途,只读用途,以及用作进行自己的同步的较大数据对象的一部分。通常,不让用户为不使用的功能付费是一种很好的API设计实践。此外,在某些情况下,不必要的同步可能会导致死锁。<br /> 如果需要线程安全的集合,则在“[ 包装实现](https://www.yuque.com/ican/canjava/dgudtu)”部分中介绍的同步包装器 允许将_任何_集合转换为同步集合。因此,同步对于通用实现是可选的,而对于传统实现则是必需的。而且,`java.util.concurrent`软件包提供了扩展`Queue`的`BlockingQueue`和扩展了`Map`的`ConcurrentMap`接口的并发实现。这些实现比单纯的同步实现提供更高的并发性。<br /> 通常,您应该考虑的是接口,_而不是_实现。这就是为什么本节中没有编程示例的原因。在大多数情况下,实现的选择仅影响性能。如“[接口](https://www.yuque.com/ican/canjava/mlrz2b)”部分所述,首选样式是选择创建`Collection`时的实现,并立即将新集合分配给相应接口类型的变量(或将集合传递给需要接口类型参数的方法)。这样,程序就不会依赖于给定实现中添加的任何方法,从而使程序员可以在性能或行为细节得到保证的任何时候自由地更改实现。<br /> 以下各节简要讨论了实现。使用诸如_常量时间_,_log_,_线性_,_n log(n)_和_二次_等词来描述实现的性能,以指代执行操作的时间复杂度的渐近上限。所有这一切都令人拗口,如果您不知道这意味着什么,那也没关系。如果您想了解更多信息,请参阅任何优秀的算法教科书。要记住的一件事是,这种性能指标有其局限性。有时,名义上较慢的实现可能会更快。如有疑问,请评估性能!