AbstractCollection类中的 T[] toArray(T[] a)方法源码解读

一、源码解读

@SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        //size为集合的大小
        int size = size();
        //当传入数组大于集合大小时,r数组就是a数组,否则创建新的数组r,数组大小为集合大小
        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()) {
                //若a和r相等,则把数组当前位置置空
                if (a == r) {
                    r[i] = null; 
                //说明数组r为新的数组,此时数组的长度介于a和r之间,将r数组拷贝进新数组,长度设为i,即真实长度
                } else if (a.length < i) {
                    return Arrays.copyOf(r, i);
                //a的长度大于i的时候,把r数组赋值给a数组,若没填满,则剩余长度赋值为null
                } else {
                    System.arraycopy(r, 0, a, 0, i);
                    if (a.length > i) {
                        a[i] = null;
                    }
                }
                //此时迭代器已经到底,且a数组够大,因此返回a数组
                return a;
            }
            //迭代器没有到底,将集合元素放入r数组。
            r[i] = (T)it.next();
        }
        //集合数据增加了,则需要扩容
        return it.hasNext() ? finishToArray(r, it) : r;
    }

二、直观的解释(区间判断)

当集合元素在获取迭代器后数量不变
    则直接将数据赋值给r数组,并返回r数组
当集合元素在获取迭代器后数量增加
    则将r数组填满后,剩余的集合元素使用finishToArray()方法填入新的数组中
当集合元素在获取迭代器后减少了
    传入的数组a足够大,则r=a
        当i<r时
            将r中剩余元素设置为null,并返回r数组
    传入的数组a不够大,装不下,则r>a
            若a<i<r
                r数组太大,需要缩短长度,将实际的元素填充r数组,r数组长度为实际集合长度
            若i=<a<r
                把r数组值复制给a数组中,此时a数组还没有填满,剩余的位置填充null

猜你喜欢

转载自www.cnblogs.com/mlr-wjy/p/12431975.html
T