java.util.AbstractCollection中的集合转换数组


//返回 Object类型的数组

public Object[] toArray() {
        Object[] r = new Object[size()];
        Iterator 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[] 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界限。所以在数组中保留8
private 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[] toArray(T[] a) {
        // 比较集合和已知数组的大小
  //
        int size = size();
        T[] r = a.length >= size ? a :
                  (T[])java.lang.reflect.Array
                  .newInstance(a.getClass().getComponentType(), size);
                  //集合迭代器
        Iterator 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(),我们可以使用它来实现数组之间的复制。(Object src,int srcPos,Object dest,int destPos,int length)。src:源数组;  srcPos:源数组要复制的起始位置;dest:目的数组;   destPos:目的数组放置的起始位置;    length:复制的长度。src and dest都必须是同类型或者可以进行转换类型的数组.
                    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;
    }

三、判断是否包含指定元素

public boolean contains(Object o) {
        Iterator it = iterator();
        //判断参数是否为null
        if (o==null) {
            while (it.hasNext())
            // 如果为null,则返回true,否则返回false
            //使用 == 比较是否相等,如果用equals,会出现空指针异常
                if (it.next()==null)
                    return true;
        } else {
            while (it.hasNext())
             //使用equals比较两个对象,
                if (o.equals(it.next()))
                    return true;
        }
        return false;
    }

四、移除集合中的指定元素

//类似于contains()方法
 public boolean remove(Object o) {
        Iterator it = iterator();
        if (o==null) {
            while (it.hasNext()) {
                if (it.next()==null) {
                    it.remove();
                    return true;
                }
            }
        } else {
            while (it.hasNext()) {
                if (o.equals(it.next())) {
                    it.remove();
                    return true;
                }
            }
        }
        return false;
    }

五、判断参数集合中的元素是否在当前集合中

//ClassCastException异常:指定集合与当前集合中的一些元素类型不一致时,
//NullPointerException异常:指定集合包含null,但是当前集合不允许是null时,

public boolean containsAll(Collection c) {
       //遍历指定的集合
        for (Object e : c)
        //如果 指定的集合中有一个元素不在当前集合中,那么返回false
            if (!contains(e))
                return false;
        //如果参数集合中所有的元素都在当前集合中,则返回true        
        return true;
    }

六、添加指定集合中的所有元素

//如果指定的集合 也是当前集合本身 (自己给自己添加元素),那结果是不确定的。


 public boolean addAll(Collection c) {
        boolean modified = false;
        for (E e : c)
           //只要集合 c 中的任何一个元素成功添加到了当前集合中,即使其它元素全部添加失败了,此方法也会返回 true
            if (add(e))
                modified = true;
        return modified;
    }

七、移除所有与指定集合相同的元素

public boolean removeAll(Collection c) {
        boolean modified = false;
        Iterator it = iterator();
        while (it.hasNext()) {
        //只要当前集合中任何一个元素被移除,即使其它元素全部移除失败了,此方法也会返回 true
            if (c.contains(it.next())) {
                it.remove();
                modified = true;
            }
        }
        return modified;
    }

八、移除当前集合中与指定集合不一致的元素

public boolean retainAll(Collection c) {
        boolean modified = false;
        Iterator it = iterator();
        while (it.hasNext()) {
        //指定的集合元素 不在 当前集合中,那么会被移除
        //即使只有一个元素被移除,也会返回true.
            if (!c.contains(it.next())) {
                it.remove();
                modified = true;
            }
        }
        return modified;
    }

九、清空集合

public void clear() {
        Iterator it = iterator();
        while (it.hasNext()) {
            it.next();
            it.remove();
        }
    }

十、返回此 collection 的字符串表示形式

public String toString() {
        Iterator it = iterator();
        //如果集合为空,返回[]
        if (! it.hasNext())
            return "[]";
//这些元素按其迭代器返回的顺序排列,并用方括号 ("[]") 括起来。相邻元素由字符 ", "(逗号加空格)分隔。
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

你可能感兴趣的:(java集合)