java.util.AbstractCollection

来源:互联网 发布:余文乐潮牌淘宝店 编辑:程序博客网 时间:2024/05/17 04:18
//返回 Object类型的数组public Object[] toArray() {        Object[] r = new Object[size()];        Iterator<E> it = iterator();        for (int i = 0; i < r.length; i++) {            if (! it.hasNext())         //实现数组的复制,返回复制后的数组。        //参数是被复制的数组和复制的长度        //复制的长度大于被复制数组的长度,则填充类型默认值,String得默认值是null,int的默认值是0。        //新建一个原数组的拷贝,并修改原数组,指向这个新建数组。原数组自动抛弃(java垃圾回收机制会自动回收)。                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;            //值得借鉴            //这是用来判断 数组r 是否需要进一步扩容            if (i == cap) {               //右移运算符,cap >> 1,相当于cap/2(取整)               //多加1,表示如果取整结果是0,避免扩容失败               //新的扩容大小newCap                int newCap = cap + (cap >> 1) + 1;                if (newCap - MAX_ARRAY_SIZE > 0)                    newCap = hugeCapacity(cap + 1);               //因为数组新建之后,大小就不可以修改,               //所以通过这种方法扩容                     r = Arrays.copyOf(r, newCap);            }            r[i++] = (T)it.next();        }        // 数组从0开始        return (i == r.length) ? r : Arrays.copyOf(r, i);    }//整形类型是有范围的,最大值为Integer.MAX_VALUE,即2147483647,最小值为Integer.MIN_VALUE -2147483648。public static final int   MAX_VALUE = 0x7fffffff;//来分配数组的size最大值。一些 VMs在数组里保留字头,试图分配更大数组时可能导致OutOfMemoryError:被请求数组的size超出VM界限。所以在数组中保留8private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//判断数组容量是否溢出,最大为整型数据的最大值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;    }

另一个集合转成数组

//返回的类型与数组的类型相同public <T> T[] toArray(T[] a) {        // 比较集合和已知数组的大小  //        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()) {             //比较的是对象的引用            //即使集合的大小变小了,但是因为a.length在一开始就大于size()                if (a == r) {                //已知数组的大小 大于 集合的大小                //将新数组在 i 之后都置为 null                    r[i] = null;                 }                //这种情况是:刚开始a.length 是小于 size()                //但是由于同步的原因,导致集合size()变小。                //此时需要再比较一次  a.leng  和 实际size 的大小                //此时  i  可以认为是 实际集合size()大小               else if (a.length < i) {                    return Arrays.copyOf(r, i);                } else {                    System.arraycopy(r, 0, a, 0, i);                    if (a.length > i) {                        a[i] = null;                    }                }                return a;            }            r[i] = (T)it.next();        }        // 可能会有同步添加元素,导致超出初始的数组大小        return it.hasNext() ? finishToArray(r, it) : r;    }
原创粉丝点击