首页 > 代码库 > AbstractCollection

AbstractCollection

概述

    这个类提供了实现Collection接口的骨架,来最小化实现此接口所做的工作。

      要实现一个不可修改的 collection,编程人员只需扩展此类,并提供 iteratorsize 方法的实现。(iterator 方法返回的迭代器必须实现 hasNextnext。)

      要实现可修改的 collection,编程人员必须另外重写此类的 add 方法(否则,会抛出 UnsupportedOperationException),iterator 方法返回的迭代器还必须另外实现其 remove 方法。

无参构造器

技术分享
    protected AbstractCollection() {
    }
View Code

抽象方法

技术分享
    public abstract Iterator<E> iterator();

    public abstract int size();
View Code

字段

技术分享
数组能容纳的最大元素个数
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
View Code

其他方法比较简单,我们看几个比较有意思的方法

System.arraycopy () 本地方法  如果是数组比较大,那么使用System.arraycopy会比较有优势,因为其使用的是内存复制,省去了大量的数组寻址访问等时间

技术分享
       * @param      src      the source array.
     * @param      srcPos   starting position in the source array.
     * @param      dest     the destination array.
     * @param      destPos  starting position in the destination data.
     * @param      length   the number of array elements to be copied.
  public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);
View Code

Arrays.copyOf()

技术分享
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]  如果newType为Object[]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);       如果不是,通过反射创建数组
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }
View Code
技术分享
    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }
View Code

public Object[] toArray()

技术分享
    public Object[] toArray() {
        // Estimate size of array; be prepared to see more or fewer elements
        Object[] r = new Object[size()];  1 
        Iterator<E> it = iterator();  2  (1和2之间数组大小可能改变)
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) //   (如果数组变小)
                return Arrays.copyOf(r, i);
            r[i] = it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r; (如果数组变大)
    }
     //数组变大,复制变大后面的元素
    private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
        int i = r.length;
        while (it.hasNext()) {
            int cap = r.length;
            if (i == cap) {
                int newCap = cap + (cap >> 1) + 1;   //扩容
                // overflow-conscious code
                if (newCap - MAX_ARRAY_SIZE > 0)
                    newCap = hugeCapacity(cap + 1);  // 限制容量
                r = Arrays.copyOf(r, newCap);
            }
            r[i++] = (T)it.next();
        }
        // trim if overallocated
        return (i == r.length) ? r : Arrays.copyOf(r, i);  
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError
                ("Required array size too large");
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
View Code

public <T> T[] toArray(T[] a)

    public <T> T[] toArray(T[] a) {
        // Estimate size of array; be prepared to see more or fewer elements
        int size = size();
        T[] r = a.length >= size ? a :  // 参数数组个数比集合元素多
                  (T[])java.lang.reflect.Array
                  .newInstance(a.getClass().getComponentType(), size);
        Iterator<E> it = iterator();

        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) { 数组元素可能改变  ,变少
                if (a != r)            如果用参数中的数组,直接null
                    return Arrays.copyOf(r, i);    否则截取数组
                r[i] = null; // null-terminate
                return r;
            }
            r[i] = (T)it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r;  变多
    }

 

AbstractCollection