Java容器类源码阅读2

128 阅读2分钟

对于容器类的功能理解:接口实现时主要的功能体现方式。Abstract类虽然实现的部分接口的功能,但是真正的容器实现并没有在Abstract类的基础上实现,而是使用的更加高效的方式。Abstract类的出现是为用户提供了方便地实现自定义容器的接口。

比如AbstractSet的实现只需要提供Size()方法和Iterator()方法,但是实际上虽然HashMap 继承了AbstractSet但是其是通过HashMap()实现的。同理的,要实现一个自定义的List,只需要给AbstractList提供一个get()方法,但是ArrayList确实通过数组实现的。

所以要理解不同容器的功能和性能,需要从两个方面理解: 第一是容器类的功能上的差异。第二是不同实现的方式的容器在性能上的差异。

List 和 Set 都是实现了与 Collection 接口的所有方法,但是在不同种类型实现的容器中,所支持的接口是可以通过UnsupportedOperationException 异常来进行选择的,特别是对于一些基于固定长度的数据结构的容器,任何的调整容器大小的方法都是不受支持的,比如Arrays.asList()方法所返回的List,Add、Remove等方法都是不受支持的。

Arrays类内部,根据AbstractList重新定义了一个ArrayList
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

/**
 * @serial include
 */
private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable

在AbstarctList中:

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

public E remove(int index) {
    throw new UnsupportedOperationException();
}

但是,如果将如Arrays.asList()方法所返回的List作为构造器参数生成的ArrayList将产生一个允许所有方法的容器。

Collections.unmodifiableList()同理将会产生一个unmodifiableCollection: 持有一个Collection,让后将Modify有关的方法适配。

static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
    private static final long serialVersionUID = 1820017752578914078L;

    final Collection<? extends E> c;

    UnmodifiableCollection(Collection<? extends E> c) {
        if (c==null)
            throw new NullPointerException();
        this.c = c;
    }

    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }
    public boolean remove(Object o) {
        throw new UnsupportedOperationException();
    }

    public boolean containsAll(Collection<?> coll) {
        return c.containsAll(coll);
    }
    public boolean addAll(Collection<? extends E> coll) {
        throw new UnsupportedOperationException();
    }
    public boolean removeAll(Collection<?> coll) {
        throw new UnsupportedOperationException();
    }
    public boolean retainAll(Collection<?> coll) {
        throw new UnsupportedOperationException();
    }
    public void clear() {
        throw new UnsupportedOperationException();
    }