先介绍几种初始化方法

// 带初始化容量的初始化
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            // 初始话一个object 数组
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            // 初始话一个空数组
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            // 抛出错误
            throw new IllegalArgumentException("Illegal Capacity: "+
                    initialCapacity);
        }
    }

    // 默认初始化
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    // 使用一个集合初始化
    public ArrayList(Collection<? extends E> c) {
        // 将集合转化成数组
        elementData = c.toArray();
        // size是arraylist的长度,赋予集合的长度
        if ((size = elementData.length) != 0) {
            // 长度不为0, 集合转化为数组后,如果类型不是object的,转为object
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // 初始化一个空数组
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

重点看下c.toArray方法,假如这个集合是个arraylist类型的,那它的toArray实现如下

    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

发现,调用的是Arrays.copyof方法

    public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }

继续看

/**
     *
     * @param original 要复制的数组
     * @param newLength 要复制的长度
     * @param newType 要复制的数组的class类型
     * @param <T>
     * @param <U>
     * @return
     */
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        // 这步的作用其实是个优化,假如newType类型是一个object类型,那就直接使用new Object来进行创建数组,加入不是,就用反射的机制创建数组
     // 优化的理由应该是:反射创建数组的性能为比直接创建的性能来的低
// (Object)newType == (Object)Object[].class 这句话就是判断newType是不是一个object类型 // newType.getComponentType() 其实是获得数组类型,假如说数组是一个String[],那这可以拿到String 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; }

 再介绍ArrayList两个操作

// 移除所有在c集合里的元素
    public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        return batchRemove(c, false);
    }

    // 保留所有在c集合里的元素
    public boolean retainAll(Collection<?> c) {
        Objects.requireNonNull(c);
        return batchRemove(c, true);
    }

    // 
    private boolean batchRemove(Collection<?> c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0, w = 0;
        boolean modified = false;
        try {
            // 根据complement判断是否保留
            for (; r < size; r++)
                if (c.contains(elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            // 假如出现错误,将这个元素后面的所有元素都放到elementData中,不在做去除操作
            if (r != size) {
                System.arraycopy(elementData, r,
                        elementData, w,
                        size - r);
                w += size - r;
            }
            // 如果没出现错误
            if (w != size) {
                // clear to let GC do its work
                // 将被去除的元素置为null
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                // 修改次数
                modCount += size - w;
                // 修改当前数组长度
                size = w;
                // 表示做过修改
                modified = true;
            }
        }
        return modified;
    }

 提下java的迭代器,通过迭代器来操作ArrayList

取得迭代器

// 返回带指定游标的迭代器ListIterator
    public ListIterator<E> listIterator(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: "+index);
        return new ListItr(index);
    }

    // 返回游标默认为0的迭代器ListIterator
    public ListIterator<E> listIterator() {
        return new ListItr(0);
    }

    // 返回默认的迭代器Iterator
    public Iterator<E> iterator() {
        return new Itr();
    }

再看下迭代器的实现

Iterator:

    private class Itr implements Iterator<E> {
        int cursor;       // 角标,下个元素的位置
        int lastRet = -1; // 上次操作的元素位置
        int expectedModCount = modCount; //用户操作ArrayList,会改变modCount

        public boolean hasNext() {
            return cursor != size; // 角标不为ArrayList长度,则表示有下一个
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification(); // 检查用户是否在操作ArrayList,如果操作不在迭代
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1; // 角标位置+1
            return (E) elementData[lastRet = i]; // 返回当前元素
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification(); // 检查用户是否在操作ArrayList,如果操作不在迭代

            try {
                ArrayList.this.remove(lastRet); // ArrayList移除这个元素
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount; // 重新赋予新的修改次数
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        // 从当前角标的位置,到结束,consumer为函数编程接口,传各个元素进去执行自定义函数,若在操作过程中,ArrayList发送了修改,则退出迭代,并抛出错误
        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }

        // 检查当前的ArrayList是否被修改
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

listItr

    private class ListItr extends Itr implements ListIterator<E> {
        // 角标设为index
        ListItr(int index) {
            super();
            cursor = index;
        }

        // 判断前面是否有元素
        public boolean hasPrevious() {
            return cursor != 0;
        }

        // 返回当前角标,就是下个元素的位置
        public int nextIndex() {
            return cursor;
        }

        // 返回当前元素的位置
        public int previousIndex() {
            return cursor - 1;
        }

        // 返回当前元素,并将角标改为当前元素的位置
        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        // 设置当前元素的值
        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.set(lastRet, e);
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        // 将值添加到当前元素之后
        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

可以看出迭代器在遍历数组时,同时可以增加删除,角标都会随之发生变化。

而如果用for循环遍历ArrayList进行添加删除操作,如果不对当前位置进行一些控制,将发生一些明显的错误。在多线程的情况,操作ArrayList,你将无法知晓其它线程是否有进行添加删除操作,两方同时操作必将发生错误。

我们可以看看下面的add操作,它只是做了添加一个元素,并将size+1,而迭代器在添加的时候会进行判断modcount是否发生改变,并将角标自动+1。保证了操作的正确性。

    // 添加 元素
    public boolean add(E e) {
        // 调整容量
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        // 赋值,并将szie+1
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        // 记得前面默认初始化ArrayList的时候,会将elementData赋值为DEFAULTCAPACITY_EMPTY_ELEMENTDATA
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            // 这时候判断当前的size和DEFAULT_CAPACITY,第一次添加,size为0,所以容量将被初始化为常量10
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
        // 修改次数+1,如果迭代器这时候再操作元素,将抛出异常,并中断迭代
        modCount++;
        // 如果minCapacity的容量大于数组中元素的长度
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //newCapacity为元素长度的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        //扩充元素
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

 

ArrayList中还有个可分割的迭代器

//可分割迭代器
    static final class ArrayListSpliterator<E> implements Spliterator<E> {
        //用于存放ArrayList对象
        private final ArrayList<E> list;
        //起始位置(包含),advance/split操作时会修改
        private int index;
        //结束位置(不包含),-1 表示到最后一个元素
        private int fence;
        //用于存放list的modCount
        private int expectedModCount;

        ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
                             int expectedModCount) {
            this.list = list;
            this.index = origin;
            this.fence = fence;
            this.expectedModCount = expectedModCount;
        }
        //获取结束位置(存在意义:首次初始化石需对fence和expectedModCount进行赋值)
        private int getFence() {
            int hi;
            ArrayList<E> lst;
            //fence<0时(第一次初始化时,fence才会小于0):
            if ((hi = fence) < 0) {
                //list 为 null时,fence=0
                if ((lst = list) == null)
                    hi = fence = 0;
                else {
                    //否则,fence = list的长度。
                    expectedModCount = lst.modCount;
                    hi = fence = lst.size;
                }
            }
            return hi;
        }
        //分割list,返回一个新分割出的spliterator实例
        // 这里要注意,index已被赋值为mid,起始位置已发生改变
        public ArrayListSpliterator<E> trySplit() {
            //hi为当前的结束位置
            //lo 为起始位置
            //计算中间的位置
            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
            //当lo>=mid,表示不能在分割,返回null
            //当lo<mid时,可分割,切割(lo,mid)出去,同时更新index=mid
            return (lo >= mid) ? null :
                    new ArrayListSpliterator<E>(list, lo, index = mid,                                         expectedModCount);
        }
        //返回true 时,只表示可能还有元素未处理
        //返回false 时,没有剩余元素处理了。。。
        // 注意index+1,角标向前移动了以为,下次再调用这个方法就是处理下个元素
        public boolean tryAdvance(Consumer<? super E> action) {
            if (action == null)
                throw new NullPointerException();
            //hi为当前的结束位置
            //i 为起始位置
            int hi = getFence(), i = index;
            //还有剩余元素未处理时
            if (i < hi) {
                //处理i位置,index+1
                index = i + 1;
                @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
                action.accept(e);
                //遍历时,结构发生变更,抛错
                if (list.modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                return true;
            }
            return false;
        }
        //顺序遍历处理所有剩下的元素
        //在这个方法里,角标index不发生变化,并处理index到fence里的元素
        public void forEachRemaining(Consumer<? super E> action) {
            int i, hi, mc; // hoist accesses and checks from loop
            ArrayList<E> lst; Object[] a;
            if (action == null)
                throw new NullPointerException();
            if ((lst = list) != null && (a = lst.elementData) != null) {
                //当fence<0时,表示fence和expectedModCount未初始化
                if ((hi = fence) < 0) { /// 注意hi在这里被赋值
                    mc = lst.modCount;
                    hi = lst.size;
                }
                else
                    mc = expectedModCount;
                if ((i = index) >= 0 && (index = hi) <= a.length) {
                    for (; i < hi; ++i) {
                        @SuppressWarnings("unchecked") E e = (E) a[i];
                        //调用action.accept处理元素
                        action.accept(e);
                    }
                    //遍历时发生结构变更时抛出异常
                    if (lst.modCount == mc)
                        return;
                }
            }
            throw new ConcurrentModificationException();
        }

        // 返回剩下元素长度
        public long estimateSize() {
            return (long) (getFence() - index);
        }

        public int characteristics() {
            //打上特征值:、可以返回size
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
    }

 使用下这个ArrayList的可分割迭代器

public static void main(String[] args) throws IOException, ClassNotFoundException {

        List<String>  arrs = new ArrayList<>();
        arrs.add("a");
        arrs.add("b");
        arrs.add("c");
        arrs.add("d");
        arrs.add("e");
        arrs.add("f");
        arrs.add("h");
        arrs.add("i");
        arrs.add("j");

        Spliterator<String> a =  arrs.spliterator();
        //运行到这里,结果:a:0-9(index-fence)

        Spliterator<String> b = a.trySplit();
        //运行到这里,结果:a:4-9 b:0-4

        Spliterator<String> c = a.trySplit();
        //运行到这里,结果:a:6-9 b:0-4 c:4-6
    }

注意,这个分割都是从index到fence,fence一般为迭代器里最大操作位置,index为当前操作的位置,如果操作了第一个元素,比如使用了tryAdvance。那index+1,则分割的时候,也是index到(index+fence)/2;分割出去。

public static void main(String[] args) throws IOException, ClassNotFoundException {

        List<String>  arrs = new ArrayList<>();
        arrs.add("a");
        arrs.add("b");
        arrs.add("c");
        arrs.add("d");
        arrs.add("e");
        arrs.add("f");
        arrs.add("h");
        arrs.add("i");
        arrs.add("j");

        Spliterator<String> a =  arrs.spliterator();
        //运行到这里,结果:a:0-9(index-fence)

        Consumer<String> t = (inputStr) -> {System.out.println(inputStr.equals("a") ? "的确为a":"不是a啊");};
        a.tryAdvance(t);
        //运行到这里,输出:的确为a

        Spliterator<String> b = a.trySplit();
        //运行到这里,结果:a:5-9 b:1-5

        Spliterator<String> c = a.trySplit();
        //运行到这里,结果:a:7-9 b:1-5 c:5-7
    }