乐趣区

ArrayList源码解读二

clear() 删除错有缓冲区里的数据

public void clear() {
        modCount++;
        final Object[] es = elementData;
        for (int to = size, i = size = 0; i < to; i++)// 实际存储数据置 0,从 0 到实际存储的位置循环置 null
            es[i] = null;
    }

addAll(Collection<? extends E> c) 添加集合到当前集合

 public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray();// 转化为数组
        modCount++;
        int numNew = a.length;// 添加数据长度
        if (numNew == 0)
            return false;// 长度为 0 直接返回 false
        Object[] elementData;
        final int s;
        if (numNew > (elementData = this.elementData).length - (s = size))// 旧数据长度 + 新数据长度大于缓冲区大小,就扩容
            elementData = grow(s + numNew);// 扩大为可以容纳旧数据 + 新数据大小
        System.arraycopy(a, 0, elementData, s, numNew);// 新数据从 0 位开始复制到缓冲区的 s 位处,复制长度为新数据长度
        size = s + numNew;
        return true;
    }

addAll(int index, Collection<? extends E> c) 添加集合到当前集合的固定位置

 public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);// 确认下标

        Object[] a = c.toArray();// 转数组
        modCount++;
        int numNew = a.length;
        if (numNew == 0)
            return false;// 长度为 0 直接返回
        Object[] elementData;
        final int s;
        if (numNew > (elementData = this.elementData).length - (s = size))// 旧数据长度 + 新数据长度大于缓冲区大小,就扩容
            elementData = grow(s + numNew);

        int numMoved = s - index;// 存储长度减去 index 得出就是要移动数据的长度
        if (numMoved > 0)
            System.arraycopy(elementData, index,elementData, index + numNew,numMoved);// 把缓冲区从 index 移动到 index + numNew,移动长度为 numMoved 
        System.arraycopy(a, 0, elementData, index, numNew);// 把集合从 0 位移动到缓冲区 index 位,共移动集合的长度个数据
        size = s + numNew;// 实际存储数更改为 size+ 集合长度
        return true;// 返回 true
    }

removeRange(int fromIndex, int toIndex) 删除介于 (包含)fromIndex 和 toIndex(不包含)的所有元素

  protected void removeRange(int fromIndex, int toIndex) {if (fromIndex > toIndex) {
            throw new IndexOutOfBoundsException(outOfBoundsMsg(fromIndex, toIndex));
        }
        modCount++;
        shiftTailOverGap(elementData, fromIndex, toIndex);
    }

shiftTailOverGap(Object[] es, int lo, int hi) 删除 lo(包含) 到 hi(不包含)期间的元素

 private void shiftTailOverGap(Object[] es, int lo, int hi) {System.arraycopy(es, hi, es, lo, size - hi);// 从 hi 位以后的数据复制到 lo 位,共复制 size-hi 个数据
        for (int to = size, i = (size -= hi - lo); i < to; i++)
            es[i] = null;// 置 0
    }

rangeCheckForAdd(int index) 判断是否在区间内

private void rangeCheckForAdd(int index) {if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

下标越界消息

private String outOfBoundsMsg(int index) {return "Index:"+index+", Size:"+size;}
    
    
private static String outOfBoundsMsg(int fromIndex, int toIndex) {return "From Index:" + fromIndex + "> To Index:" + toIndex;}

removeAll(Collection<?> c) 删除缓冲区中,集合包含的数据

 public boolean removeAll(Collection<?> c) {return batchRemove(c, false, 0, size);
    }

retainAll(Collection<?> c) 保留缓冲区中,集合包含的数据

public boolean retainAll(Collection<?> c) {return batchRemove(c, true, 0, size);
    }

batchRemove(Collection<?> c, boolean complement,final int from, final int end)false 是删除传入集合包含元素,true 是保留传入集合包含元素

boolean batchRemove(Collection<?> c, boolean complement,
                        final int from, final int end) {Objects.requireNonNull(c);
        final Object[] es = elementData;
        int r;
        // Optimize for initial run of survivors
        for (r = from;; r++) {if (r == end)// 操作长度为 0 直接返回 false
                return false;
            if (c.contains(es[r]) != complement)// 为 true 的时候,查找到第一个不保留位 r。为 false 时候查找到第一个要删除的位
                break;
        }
        int w = r++;
        try {for (Object e; r < end; r++)
                if (c.contains(e = es[r]) == complement)// 为 true 时把在集合的元素往前移,为 false 时,不在集合的元素往前移动
                    es[w++] = e;
        } catch (Throwable ex) {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            System.arraycopy(es, r, es, w, end - r);
            w += end - r;
            throw ex;
        } finally {
            modCount += end - w;
            shiftTailOverGap(es, w, end);// 删除尾部元素
        }
        return true;
    }

writeObject(java.io.ObjectOutputStream s) 输出对象

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        // Write out element count, and any hidden stuff
        int expectedModCount = modCount;
        s.defaultWriteObject();

        // Write out size as capacity for behavioral compatibility with clone()
        s.writeInt(size);

        // Write out all elements in the proper order.
        for (int i=0; i<size; i++) {s.writeObject(elementData[i]);// 循环输出对象
        }

        if (modCount != expectedModCount) {throw new ConcurrentModificationException();// 线程安全
        }
    }

readObject(java.io.ObjectInputStream s) 读取对象

private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {

        // Read in size, and any hidden stuff
        s.defaultReadObject();

        // Read in capacity
        s.readInt(); // ignored

        if (size > 0) {// 数据量大于 0
            // like clone(), allocate array based upon size not capacity
            SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
            Object[] elements = new Object[size];

            // Read in all elements in the proper order.
            for (int i = 0; i < size; i++) {elements[i] = s.readObject();}

            elementData = elements;
        } else if (size == 0) {// 数据量等于 0
            elementData = EMPTY_ELEMENTDATA;
        } else {throw new java.io.InvalidObjectException("Invalid size:" + size);
        }
    }

listIterator() 返回迭代器

public ListIterator<E> listIterator() {return new ListItr(0);
    }

listIterator(int index) 返回迭代器

public ListIterator<E> listIterator(int index) {rangeCheckForAdd(index);//
        return new ListItr(index);
    }
退出移动版