通过Collection实现类创建ArrayList(含源码解析)

ArrayList(Collection c) 此构造器允许我们方便快捷的将Collection体系下的集合转换成ArrayList.
如下实现类均作为参数(since 1.8)

AbstractCollection AbstractList AbstractQueue AbstractSequentialList
AbstractSet ArrayBlockingQueue ArrayDeque ArrayList
AttributeList BeanContextServicesSupport BeanContextSupport ConcurrentHashMap.KeySetView
ConcurrentLinkedDeque ConcurrentLinkedQueue ConcurrentSkipListSet CopyOnWriteArrayList
CopyOnWriteArraySet DelayQueue EnumSet HashSet
JobStateReasons LinkedBlockingDeque LinkedBlockingQueue LinkedHashSet
LinkedList LinkedTransferQueue PriorityBlockingQueue PriorityQueue
RoleList RoleUnresolvedList Stack SynchronousQueue
Vector TreeSet

源码如下:

public ArrayList(Collection c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // 存在可能获取的数组类型不是Object[]类型,需要判断下,是则进行拷贝一个新的Object[]用于存储
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // size=0则为一个空数组{}
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

elementData :Object[] elementData,是一个ArrayList用于存储元素的数组。toArray是Collection接口的方法,其实现类都重写了这个方法,用于依次的获取容器的元素,例如ArrayList的toArray()方法:

//底层是调用System.arraycopy方法进行拷贝操作
public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

注意存在可能获取的数组类型不是Object[]类型,详见https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652【JDK bug data】,所以需要判断下类型,如果不是Object[]则需要进行拷贝并生成新的Object[]对象,源码如下:

public static  T[] copyOf(U[] original, int newLength, Class newType) {
        @SuppressWarnings("unchecked")
        //如果都是Object[]则新建一个Object[]数组,否则新建一个newType类型的数组
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        //拷贝
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

实战例子:

public class GenericVarargs {

    public static  List makeList(T... args){
        List result = new ArrayList<>(Arrays.asList(args));
        return result;
    }

    public static void main(String[] args) {
        List ls = makeList("A","B","C");
        System.out.println(ls);
    }
}

结果:

[A, B, C]

你可能感兴趣的:(Java)