文档

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

课程:自定义集合实现

许多程序员永远不需要实现自己的 Collection 类。你可以使用本章前面部分中描述的实现进行相当久的操作。但是,有一天你可能想编写自己的实现。借助 Java 平台提供的抽象实现,这很容易做到这一点。在我们讨论 如何 编写实现之前,让我们讨论一下为什么要编写一个实现。

编写实现的原因

以下列表说明了你可能希望实现的自定义 Collection 的类型。它并非详尽无遗:

如何编写自定义实现

编写自定义实现非常简单。Java 集合框架提供了明确设计的抽象实现,以方便自定义实现。我们将从以下 Arrays.asList 的实现示例开始。

public static <T> List<T> asList(T[] a) {
    return new MyArrayList<T>(a);
}

private static class MyArrayList<T> extends AbstractList<T> {

    private final T[] a;

    MyArrayList(T[] array) {
        a = array;
    }

    public T get(int index) {
        return a[index];
    }

    public T set(int index, T element) {
        T oldValue = a[index];
        a[index] = element;
        return oldValue;
    }

    public int size() {
        return a.length;
    }
}

信不信由你,这非常接近 java.util.Arrays 中包含的实现。就这么简单!你提供构造函数和 getsetsize 方法,AbstractList 完成其余所有操作。你可以免费获得 ListIterator,批量操作,搜索操作,哈希码计算,比较和字符串表示。

假设你希望实现更快一点。抽象实现的 API 文档精确描述了每个方法的实现方式,因此你将知道要覆盖哪些方法以获得所需的性能。前面的实现的性能很好,但可以稍微改进一下。特别是,toArray 方法遍历 List,一次复制一个元素。鉴于内部表示,克隆数组的速度更快,更明智。

public Object[] toArray() {
    return (Object[]) a.clone();
}

通过添加此覆盖以及更多类似覆盖,此实现正是 java.util.Arrays 中的实现。为了完全公开,使用其他抽象实现有点困难,因为你必须编写自己的迭代器,但它仍然不是那么困难。

以下列表总结了抽象实现:

编写自定义实现的过程如下:

  1. 从前面的列表中选择适当的抽象实现类。
  2. 为类的所有抽象方法提供实现。如果你的自定义集合是可修改的,则还必须覆盖一个或多个具体方法。抽象实现类的 API 文档将告诉你要覆盖哪些方法。
  3. 测试并在必要时调试实现。你现在有一个可用的自定义集合实现。
  4. 如果你担心性能,请阅读你继承其实现的所有方法的抽象实现类的 API 文档。如果有任何看起来太慢,请覆盖它们。如果覆盖任何方法,请确保在覆盖之前和之后测量方法的性能。你在调整性能方面付出的努力应该取决于实现将获得多少使用以及对其使用性能的关键程度。(通常最好省略此步骤。)

Previous page: Previous Lesson
Next page: Interoperability