解释ArrayList的源码

package java.util;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import sun.misc.SharedSecrets;
实现RandomAccess这个接口的 List 集合是支持快速随机访问,for循环比迭代器快
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    private static final long serialVersionUID = 8683452581122892189L;

//默认初始容量为10个,也就是如果初始化数组的时候不指定ArrayList大小,

默认为10个。

ArrayList<String> strs = new ArrayList<String>();使用无参构造方法时并

没有初始化数组大小,会默认大小为10,但是在初始化的时候不会设置为10个,

会在第一次执行add操作的时候扩容为10个
    private static final int DEFAULT_CAPACITY = 10;


//如果初始化size设置为0的话,会使用这一个数组

private static final Object[] EMPTY_ELEMENTDATA = {};

    如果使用无参构造方法创建的ArrayList实例,会使用这一个数组。使用这个也是

区分其他的创建实例的方式,来判断初始化数组的大小。
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

//真正存储ArrayList数据的数组,不用private修饰是为了让内部类访问简单一些
    transient Object[] elementData;
   

//数组的大小,并不是elementData的大小,是实际存放元素的个数。
    private int size;

    //构造一个具有指定初始容量的空列表。 如果初始化容量>0,new一个初始化容量

//的数组,赋值给elementData ,如果=0,使用共用变量,否则<0,抛出异常

public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

 

//使用无参构造方法时,直接使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    //通过一个集合创建ArrayList,将传入集合中的元素一个个地放进数组中。
    public ArrayList(Collection<? extends E> c) {
        Object[] a = c.toArray();//该方法不传参数只能返回Object类
        if ((size = a.length) != 0) {
            if (c.getClass() == ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            // replace with empty array.
            elementData = EMPTY_ELEMENTDATA;
        }
    }

 

//modCount:在父类中AbstractList中定义的,初始为0,判断这个ArrayList

//结构上被修改的次数,一般用于fast-fail模式,当这个ArrayList的迭代器

//调用next、remove、previous、set、add方法的时候,会通过ArrayList的

//这个字段判断数组是否发生变化,如果发生了变化,将报出异常。

 

//这个方法的作用是将ArrayList中存放元素的Array的大小调整为实际元素

//的个数。减少ArrayList实例的存储空间,如果大小为0的话,赋值为

//EMPTY_ELEMENTDATA

public void trimToSize() {
        modCount++;
        if (size < elementData.length) {
            elementData = (size == 0)
              ? EMPTY_ELEMENTDATA
              : Arrays.copyOf(elementData, size);
        }
    }
 
    //array的最大能扩容到的长度     

//有些VM在array中需要一个头部的数据,所以要-8
    //如果大小超过这个大小,可能出现内存溢出的异常

//如果你的数组大小不能设置成这么大,可能是VM配置或硬件问题(这个没有研究过)

//https://blog.csdn.net/weixin_30810583/article/details/96248144(看看这个)

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

//大容量扩容,这个函数只能是尽量给你扩容,但是能不能扩还要看VM支持不支持,

//详见上面的MAX_ARRAY_SIZE解释

private static int hugeCapacity(int minCapacity) {

//如果数值太大导致内存溢出,出现负数的情况,直接抛出异常
        if (minCapacity < 0)

       throw new OutOfMemoryError();

//如果数值大于MAX_ARRAY_SIZE,只能赌一下你的VM不会在array中添加一个头部的数据
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

//扩容以确保它至少可以容纳参数指定的元素数。

//这块代码可能出现溢出的情况
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;

//java策略产生的扩容数量,即1.5*原来的的容量,右移为*0.5
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //如果java默认策略的扩容数量无法达到参数指定的最小容量,那么放弃默认策略,

//按照参数指定的容量进行扩容,如果默认策略大,就按照策略的。

if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;

//判断扩容后的容量是否>数组的最大容量,可能出现风险,要用参数的试一下,因为

//对于本次扩容扩容来说,参数值肯定是最小的,试试这个最小值(newCapacity可能

//因为比参数大,导致用的是策略的值)。

  if (newCapacity - MAX_ARRAY_SIZE > 0)

//执行大容量扩容的函数,这个函数可能会出现异常
            newCapacity = hugeCapacity(minCapacity);

//将原来的数组复制到一个新的数组中(新数组的长度是扩容后的长度)
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    //作用就是根据传过来的容量,判断是不是需要扩容,只有需要的容量大于当前容量,才要扩容

private void ensureExplicitCapacity(int minCapacity) {

 //这个modCount++执行了,但是如果需要的容量<=当前容量的时候,ArrayList的结构是

//不会发生变化的,也就是说modCount变化并不代表真的变了。Iterator抛出异常并不代表

//ArrayList变了
        modCount++;
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    

//根据参数去扩大ArrayList的容量
    public void ensureCapacity(int minCapacity) { 

//判断是不是通过无参构造方法创建的ArrayList实例(只有用无参构造方法才会是这个)

//如果是的话,他的默认大小已经是10了,所以不能比他小

///如果不是,可以是任意数,因为如果是其他的方法创建的实例,大小可能是>0的任意数
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)

            ? 0
            : DEFAULT_CAPACITY;
        //只有符合最小值才能去扩展
        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    }
 

//这个方法和上面的方法的区别是:

//ensureCapacity:如果传入的minCapacity不符合最小的值,就不会进一步给你扩容了,可能是你

//数字输入错误,但是方法方法不知不觉的不给你执行下面的扩容

//ensureCapacityInternal:如果传入的minCapacity不符合扩容最小值,会计算出一个合适的值去

执行下面的扩容过程

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

//通过传入的最小参数,给出一个适合的扩展值。和ensureCapacityInternal配合使用
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

 
   
    //返回ArrayList的元素数量(不是总容量)

public int size() {
        return size;
    }

    //判断ArrayList中是否有元素
    public boolean isEmpty() {
        return size == 0;
    }

 

//如果参数在ArrayList中存在(equals(包括null)),则返回true,否则,返回false,详见indexOf函数
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

   //查询出该元素在ArrayList中第一次出现的位置,如果不存在则返回-1,通过equals进行判断
    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

    

//查询出该元素在ArrayList中最后一次出现的位置,如果不存在则返回-1,通过equals进行判断

//这个可以记一下,第一次出现的位置从第一个开始遍历,最后一次出现的位置从最后一个开始遍历

public int lastIndexOf(Object o) {
        if (o == null) {
            for (int i = size-1; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = size-1; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

//ArrayList的一个浅克隆

//深克隆(虽然说v.elementData对象变化了,但是这个elementData数组中的引用却由于copyOf是

一个浅拷贝,elementData中元素的对象引用没有发生变化,当这个elementData中的元素发生变化

时,被克隆和克隆的对象都会变化。所以这个是一个浅拷贝被克隆的对象和克隆的对象内部出现一个

相同的引用,都不叫深克隆)

  public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();

//把里面的元素拷贝一份
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
                throw new InternalError(e);
        }
    }

   //ArrayList转化成Array
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

    //将ArrayList中的内容放到传进来的数组中

//如果传进来的数组小于ArrayList的大小,直接重新建一个数组传出去

//否则将ArrayList中的元素拷贝进传进来的数组中

//如果传进来的数组大于ArrayList的大小,在index=size的位置置为null,

//用来判断结尾。在程序中设置为null是为了放置传进来的数组里面有内容。
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }
    

//访问ArrayList中固定位置的元素
    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }


    //检测传进来的下标是否合理(0~size),很多方法用到,所以单独出来的方法,不去判断<0

//让数组自己报错。
    private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

 

//访问ArrayList中固定位置的元素,多了一个rangeCheck,外面直接调用这个就行

public E get(int index) {
        rangeCheck(index);
        return elementData(index);
    }

    //使用一个元素替代指定位置原来的元素
    public E set(int index, E element) {
        rangeCheck(index);
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

    //在ArrayList中的array最后添加元素
    public boolean add(E e) {

//调用这个方法会使modCount+1
        ensureCapacityInternal(size + 1);

//size+1并设值,这个写法很不错

//element[size] = e ;size ++ => elementData[size++] = e;

  elementData[size++] = e;
        return true;
    }

    //在指定位置添加元素,并将该位置和该位置后面的元素后移

public void add(int index, E element) {
        rangeCheckForAdd(index);

//每次添加元素前都要看看是不是要扩容
        ensureCapacityInternal(size + 1);  

//arraycopy不仅仅用于两个数组,可以一个数组之间复制

System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

//删除指定位置的元素,并且将该元素后面的往前移动,返回删除的元素
      public E remove(int index) {
        rangeCheck(index);
        modCount++;
        E oldValue = elementData(index);
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,numMoved);

//elementData[size]=null ; size--
        elementData[--size] = null;
        return oldValue;
    }

    //删除ArrayList中的指定元素(第一个出现的),并返回删除结果
    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

   //和上面删除一样,不过不需要进行范围检查,
    private void fastRemove(int index) {

//删除需要修改modCount
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null;

 }

   //将ArrayList中的元素置为null,并且将size变成0
    public void clear() {
        modCount++;

for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }

   //将一个集合中的元素加入到ArrayList的array中
    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }

    //将集合中的元素插入到ArrayList中,插入位置和插入位置后的元素移动集合的长度个单位,返回

添加的结果

public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount

        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,numMoved);

        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }
    //将ArrayList下标范围内的元素删除
       protected void removeRange(int fromIndex, int toIndex) {
        modCount++;
        int numMoved = size - toIndex;
        System.arraycopy(elementData, toIndex, elementData, fromIndex,
                         numMoved);

        // clear to let GC do its work
        int newSize = size - (toIndex-fromIndex);
        for (int i = newSize; i < size; i++) {
            elementData[i] = null;
        }
        size = newSize;
    }

 
    //添加元素时做的范围检查,这个必须要判断是否小于0,因为添加的时候会有下面的操作

//扩容或者调整元素,如果在调整过程中发现越界,前面的操作无法撤回。Index为什么要

//小于等于size:System.arraycopy(elementData, index, elementData, index + 1,
    //size - index);如果index>size,最后一个参数<0,这个函数会报错,但是=0可以不移动
    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;
    }

    //将ArrayList中包含的c集合的元素删除掉,需要判断c不为null.
    public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        return batchRemove(c, false);
    }

    //和removeAll相反,这个方法留下的是和c集合的元素相同的元素.
    public boolean retainAll(Collection<?> c) {
        Objects.requireNonNull(c);
        return batchRemove(c, true);
    }

//批量删除ArrayList中的元素,通过complement来判断是否保留/删除c的元素。

private boolean batchRemove(Collection<?> c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0, w = 0;

//设置更改状态为false
        boolean modified = false;
        try {
            for (; r < size; r++)

//遍历整个array,将需要保留的数据放在前面
                if (c.contains(elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {

//这个注释也不知道是什么意思
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.  

//如果发生异常导致未遍历完成,那么将未遍历的元素放在后面,当成是需要保留的数据
            if (r != size) {
                System.arraycopy(elementData, r,elementData, w,size - r);

//保留的数据个数需要添加上后面没有遍历的数据个数
                w += size - r;
            }
            //将保留的数据后面的位置置为空,并且更改size为保留的数据的个数

if (w != size) {
                // clear to let GC do its work
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }

 
    //将ArrayList序列化到文件中。用ObjectOutputStream的writeObject方法时会调用这

个方法去写入磁盘

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 behavioural 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();
        }
    }

 

 

 

 

 


    //通过文件流反序列化成ArrayList对象
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;
        s.defaultReadObject();
        s.readInt(); // ignored
        if (size > 0) {
            int capacity = calculateCapacity(elementData, size);
            SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
            ensureCapacityInternal(size);

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


    //ArrayList内部自己定义的Iterator
    private class Itr implements Iterator<E> {
        int cursor;       //下一个返回元素的索引

    int lastRet = -1; //当前遍历到的位置的索引

int expectedModCount = modCount;记录创建迭代器的modCount

        Itr() {} //无参构造方法
       //判断是否遍历完成,后面是否有元素

public boolean hasNext() {
            return cursor != size;
        }
        //判断在迭代器(Itr)创建之后ArrayList是否发生变化,如果发生变化,直接抛出异常
        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

//获取cursor处的元素(即下一个元素,因为cursor指的是当前遍历的下一个位置)
        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();

//共享的变量都不可靠
            int i = cursor;

if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();

//游标往后移动一位,下一个位置
            cursor = i + 1;

//返回当前遍历到的元素,并且修改当前位置LastRet,因为下一个已经取出来了,所以当前

//位置应该修改
            return (E) elementData[lastRet = i];
        }
        删除当前遍历到的元素(只能删除最后一次遍历到的元素,如果这个元素被删除,lastRet需

要变成-1,如果不变的话,下一次调用删除这时候删除的就不是最后一次遍历到的元素了,删

除不能乱删除,如果说lastRet不变的话,这个删除函数就没有道理了,我函数没有指定哪个下

标的元素,就给我删除了,这不是乱删除吗,如果我置成-1,这个函数的原理就是删除最后一次

遍历到的元素,在删除一次后下一次就不能删除了。因为当前遍历到的元素已经没了。所以置成

-1)
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {

//调用ArrayList自己的方法去删除ArrayList的元素
                ArrayList.this.remove(lastRet);

//cursor移动到当前位置,因为是删除了一个,所以下一次遍历应该是当前位置
                cursor = lastRet;

//lastRet修改为-1

lastRet = -1;

//同步modCount的值
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

 

//对剩余的元素进行操作(从cursor开始到最后),consumer.accept是对剩余元素的操作)

//Consumer是函数式接口.
        @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();
            }

//当没有遍历到最后一个元素且ArrayList没有被其他程序修改的时候。
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            

            //重新修改cursor的值,如果这样的话,其实这个函数针对的是最后面的几个操作相同,前面的操作不同的情况,最后这几个直接一次遍历完

cursor = i;

//修改lastRet
            lastRet = i - 1;
            checkForComodification();
        }

 

//ArrayList自己定义的一个ListIterator
        private class ListItr extends Itr implements ListIterator<E> {

//传入起始位置,从该位置开始遍历
        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) {

//lastRet<0说明当前元素已经删除或者迭代器还没有遍历,所以说没有当前遍历到的元素
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {

//调用ArrayList自己的方法去修改ArrayList的元素
                ArrayList.this.set(lastRet, e);
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

//在当前遍历到的位置添加一个元素
        public void add(E e) {
            checkForComodification();
            try {
                int i = cursor;

//调用ArrayList自己的方法在当前位置去添加元素                

ArrayList.this.add(i, e);
                cursor = i + 1;

//因为当前位置已经不是遍历到的元素了,所以置为-1

lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

  

 //创建一个ListItr,从ArrayList的指定位置开始

public ListIterator<E> listIterator(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: "+index);
        return new ListItr(index);
    }

    //创建一个ListItr,从ArrayList的第一个位置开始

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

//创建一个Itr,从ArrayList的第一个位置开始
    public Iterator<E> iterator() {
        return new Itr();
    }

    //使用自己的内部类截取ArrayList本身的一部分
    public List<E> subList(int fromIndex, int toIndex) {

//截取之前对截取的位置做一下判断
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList(this, 0, fromIndex, toIndex);
    }
    //对截取的位置进行判断
    static void subListRangeCheck(int fromIndex, int toIndex, int size) {
        if (fromIndex < 0)
            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
        if (toIndex > size)
            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
        if (fromIndex > toIndex)
            throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                               ") > toIndex(" + toIndex + ")");
    }
    

    //截取ArrayList中的一部分。需要注意的是,这个内部类只能被外部类调用

    //因为这个内部类由private修饰,无法使用Out.In in = new Out().new In()

    //这种方式被其他的类访问,而外部类中调用内部类的方法为subList方法,它

    //调用这个类的构造方法时,传进来的参数是ArrayList本身。所以这个内部类

    //主要的作用就是截取外部类实例的一部分,并不能截取其他的对象。然后其实

    //这个类的操作是和ArrayList相似的,且大多调用的是ArrayList本身的方法,

    //唯一不一样的是起始位置不同,所以subList中的方法和ArrayList本身的操作

    //就是多了一个偏移量。这部分将粗略说明,如果不懂,可以看ArrayList的同名

//方法。还有就是subList中的所有操作都是针对外部类对象ArrayList中的内容

//进行修改的

    private class SubList extends AbstractList<E> implements RandomAccess {

//原来的集合,其实就是外部类的实例
        private final AbstractList<E> parent;
        private final int parentOffset;

private final int offset;
        int size;
        SubList(AbstractList<E> parent,int , int fromIndex, int toIndex) {
            this.parent = parent; //外部类实例本身
            this.parentOffset = fromIndex;  //截取开始位置
            this.offset = offset + fromIndex; //offset是0,所以offset = parentOffset
            this.size = toIndex - fromIndex; //截取的长度
            this.modCount = ArrayList.this.modCount;//因为截取的是外部类实例本身,所以用外部

类的modCount
        }
        

    //判断该位置是否超出了subList的边界

private void rangeCheck(int index) {
             if (index < 0 || index >= this.size)
                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }

    

    //判断外部的modCount是否发生变化,也就是他的结构是否发生变化

    private void checkForComodification() {
            if (ArrayList.this.modCount != this.modCount)
                throw new ConcurrentModificationException();
         }

//修改index处的值,注意一点:这个subList的策略是:当执行set、get操作时

//考虑了偏移量(offset),其他的情况并没有计算偏移量。也就是说外面

//传递进来的offset是用于获取某个index处的值或者设置某一个index处的值时用的。

//,如果是截取的subList的外部类对象,其实是没有问题的,因为外部类调用时offset

//设置的是0,对于结果上来说没有影响。但是我不是很清楚这样设计的用意,就不解释了。

//如果某一天其他的对象调用到了这个私有内部类(应该不太可能),就需要注意了,设置

//获取的时候使用了偏移量,其他情况没有使用偏移量。看看subList的方法是否会对结果

//有影响。

public E set(int index, E e) {
            rangeCheck(index);
            checkForComodification();

//使用ArrayList.set相同的做法,不同的是index是加了offset

//下面很多都是这样的
            E oldValue = ArrayList.this.elementData(offset + index);
            ArrayList.this.elementData[offset + index] = e;
            return oldValue;
       }


        //获取index处的值
        public E get(int index) {
            rangeCheck(index);
            checkForComodification();

//这里也是计算了偏移量
            return ArrayList.this.elementData(offset + index);
        }

//返回subList的长度,也就是截取的长度
        public int size() {
            checkForComodification();
            return this.size;
        }
        

//在index处添加一个元素,添加元素时没有考虑offset偏移量的问题

public void add(int index, E e) {
            rangeCheckForAdd(index);
            checkForComodification();

//调用父类的add方法,是从截取的初始位置开始计算的。

//很正常的操作
            parent.add(parentOffset + index, e);

//外部类对象结构变化了,需要重新获取modCount
            this.modCount = parent.modCount;

//虽然针对外部类进行操作,且fromIndex和toIndex没有变化,但是size还是要++,

//刚开始的fromIndex和toIndex是为了第一次初始化的,以后就没什么用了,因为

//对subList执行了add操作,所以从逻辑上讲subList的长度是要+1的

            this.size++;
        }
        //删除某一个位置的数据
        public E remove(int index) {
            rangeCheck(index);
            checkForComodification();
            E result = parent.remove(parentOffset + index);
            this.modCount = parent.modCount;
            this.size--;
            return result;
        }
        //删除一个范围内的数据
        protected void removeRange(int fromIndex, int toIndex) {
            checkForComodification();
            parent.removeRange(parentOffset + fromIndex,
                               parentOffset + toIndex);
            this.modCount = parent.modCount;
            this.size -= toIndex - fromIndex;
        }

//将c中的元素全部添加到subList的末尾
        public boolean addAll(Collection<? exends E> c) {
            return addAll(this.size, c);
        }
        //在index位置把c中的元素全部添加
        public boolean addAll(int index, Collection<? extends E> c) {
            rangeCheckForAdd(index);
            int cSize = c.size();
            if (cSize==0)
                return false;

            checkForComodification();
            parent.addAll(parentOffset + index, c);
            this.modCount = parent.modCount;
            this.size += cSize;
            return true;
        }
        //将subList生成一个迭代器,调用的是父类AbstractList中的方法,从subList的第

//0位开始遍历

public Iterator<E> iterator() {
            return listIterator();
        }
         //将subList生成一个迭代器,调用的是父类AbstractList中的方法,从subList的第

//index位开始遍历
        public ListIterator<E> listIterator(final int index) {
            checkForComodification();
            rangeCheckForAdd(index);
            final int offset = this.offset;
            //一个匿名内部类,实现了ListIterator接口,操作和ArrayList的迭代器操作差不多
            return new ListIterator<E>() {
                int cursor = index;
                int lastRet = -1;
                int expectedModCount = ArrayList.this.modCount;
                
                public boolean hasNext() {
                    return cursor != SubList.this.size;
                }
                //subList的迭代器的原则和sublist的原则一样,设置、获取元素时,考虑偏移

//添加删除不考虑偏移
                @SuppressWarnings("unchecked")
                public E next() {
                    checkForComodification();
                    int i = cursor;
                    if (i >= SubList.this.size)
                        throw new NoSuchElementException();
                    Object[] elementData = ArrayList.this.elementData;
                    if (offset + i >= elementData.length)
                        throw new ConcurrentModificationException();
                    cursor = i + 1;
                    return (E) elementData[offset + (lastRet = i)];
                }

                public boolean hasPrevious() {
                    return cursor != 0;
                }

                @SuppressWarnings("unchecked")
                public E previous() {
                    checkForComodification();
                    int i = cursor - 1;
                    if (i < 0)
                        throw new NoSuchElementException();
                    Object[] elementData = ArrayList.this.elementData;
                    if (offset + i >= elementData.length)
                        throw new ConcurrentModificationException();
                    cursor = i;
                    return (E) elementData[offset + (lastRet = i)];
                }

                @SuppressWarnings("unchecked")
                public void forEachRemaining(Consumer<? super E> consumer) {
                    Objects.requireNonNull(consumer);
                    final int size = SubList.this.size;
                    int i = cursor;
                    if (i >= size) {
                        return;
                    }
                    final Object[] elementData = ArrayList.this.elementData;
                    if (offset + i >= elementData.length) {
                        throw new ConcurrentModificationException();
                    }
                    while (i != size && modCount == expectedModCount) {
                        consumer.accept((E) elementData[offset + (i++)]);
                    }
                    // update once at end of iteration to reduce heap write traffic
                    lastRet = cursor = i;
                    checkForComodification();
                }

                public int nextIndex() {
                    return cursor;
                }

                public int previousIndex() {
                    return cursor - 1;
                }

                public void remove() {
                    if (lastRet < 0)
                        throw new IllegalStateException();
                    checkForComodification();

                    try {
                        SubList.this.remove(lastRet);
                        cursor = lastRet;
                        lastRet = -1;
                        expectedModCount = ArrayList.this.modCount;
                    } catch (IndexOutOfBoundsException ex) {
                        throw new ConcurrentModificationException();
                    }
                }

                public void set(E e) {
                    if (lastRet < 0)
                        throw new IllegalStateException();
                    checkForComodification();

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

                public void add(E e) {
                    checkForComodification();

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

                final void checkForComodification() {
                    if (expectedModCount != ArrayList.this.modCount)
                        throw new ConcurrentModificationException();
                }
            };
        }
        //subList还可以再次截取,变成另外一个subList,但是操作的还是外部类对象
        public List<E> subList(int fromIndex, int toIndex) {
            subListRangeCheck(fromIndex, toIndex, size);
            return new SubList(this, offset, fromIndex, toIndex);
        }
        

//判断index是否超出sublist的范围
        private void rangeCheck(int index) {
             if (index < 0 || index >= this.size)
                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
       }


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

        private String outOfBoundsMsg(int index) {
            return "Index: "+index+", Size: "+this.size;
        }

        //将subList转换成ArrayListSpliterator,其中开始位置设置为offset,结束位置为offset

+subList的大小
        public Spliterator<E> spliterator() {
            checkForComodification();
            return new ArrayListSpliterator<E>(ArrayList.this, offset,
                                               offset + this.size, this.modCount);
        }
    }
    //将ArrayListlist中的元素做同一个操作,就是相当于for循环,传递的Consumer函数接口就是对

//ArrayList中所有元素的操作
    @Override
    public void forEach(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        final int expectedModCount = modCount;
        @SuppressWarnings("unchecked")
        final E[] elementData = (E[]) this.elementData;
        final int size = this.size;
        for (int i=0; modCount == expectedModCount && i < size; i++) {
            action.accept(elementData[i]);
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }

//将ArrayList生成一个spliterator
   @Override
    public Spliterator<E> spliterator() {
        return new ArrayListSpliterator<>(this, 0, -1, 0);
    }

    //实现util包中的Spliterator接口(可以被切割的迭代器)
    static final class ArrayListSpliterator<E> implements Spliterator<E> {

private final ArrayList<E> list;
private int index;
private int fence;

private int expectedModCount;


        ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
                             int expectedModCount) {
            this.list = list;  //被迭代的ArrayList本身

  this.index = origin; //起始位置orgin翻译过来也是有原点起源的意思
            this.fence = fence; //最终位置
            this.expectedModCount = expectedModCount;
        }

        private int getFence() {
            int hi; // (a specialized variant appears in method forEach)
            ArrayList<E> lst;

//第一次调用getFence()的时候,因为ArrayList传进来为-1,相当于初始化fence
            if ((hi = fence) < 0) {

     //如果传进来的list是null,设置fence设置为0
                if ((lst = list) == null)
                    hi = fence = 0;

     //否则设置ArrayList的size,所以fence记录的是ArrayList的大小,并且初始化

//expectedModCount为list的modcount,方便查看ArrayList是否发生结构性变化
                else {
                    expectedModCount = lst.modCount;
                    hi = fence = lst.size;
                }
            }

//返回ArrayList的大小
            return hi;
        }
        //将这个ArrayListSpliterator拆分为两个ArrayListSpliterator
        public ArrayListSpliterator<E> trySplit() {

//得到中间的位置右移一位相当于是/2
            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;

//如果初始位置>=最后的位置,说明已经不能再去分割了
            return (lo >= mid) ? null : // divide range in half unless too small

//如果能够分割,将右边的一半赋值给新的ArrayListSpliterator,并未进行真正的

//只是将两个ArrayListSpliterator的可操作性区域进行了设定
                new ArrayListSpliterator<E>(list, lo, index = mid,
                                            expectedModCount);
        }
        //获取遍历到的元素,并按照传进来的实现的接口的方法进行操作
        public boolean tryAdvance(Consumer<? super E> action) {
            if (action == null)
                throw new NullPointerException();
            int hi = getFence(), i = index;

//判断index是否超过ArrayListSpliterator的最大范围
            if (i < hi) {

//将index移动到下一个

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到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) {
                if ((hi = fence) < 0) {
                    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(e);
                    }
                    if (lst.modCount == mc)
                        return;
                }
            }
            throw new ConcurrentModificationException();
        }
        //返回剩余元素个数
        public long estimateSize() {
            return (long) (getFence() - index);
        }
        //返回该Spliterator的特性
        public int characteristics() {
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
    }

//根据传进来的Predicate函数式接口,来判断元素是否要被删除,根据他来删除元素
    @Override
    public boolean removeIf(Predicate<? super E> filter) {

//每次都是先判断传递进来的是不是非空
        Objects.requireNonNull(filter);

//初始化要删除的元素个数为0
        int removeCount = 0;

//创建一个bitSet来记录要删除的元素的下标
        final BitSet removeSet = new BitSet(size);
        final int expectedModCount = modCount;
        final int size = this.size;
        for (int i=0; modCount == expectedModCount && i < size; i++) {
            @SuppressWarnings("unchecked")
            final E element = (E) elementData[i];
            if (filter.test(element)) {

//如果该元素需要被删除,将这个位置记录下来
                removeSet.set(i);
                removeCount++;
            }
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        //通过要删除元素的个数是否>0来判断是否执行删除
        final boolean anyToRemove = removeCount > 0;
        if (anyToRemove) {
            final int newSize = size - removeCount;
            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {

//得到i的下一个不应该被删除的位置(包括i本身)
                i = removeSet.nextClearBit(i);
                elementData[j] = elementData[i];
            }

//将后面的元素补充null
            for (int k=newSize; k < size; k++) {
                elementData[k] = null;  // Let gc do its work
            }
            this.size = newSize;
            if (modCount != expectedModCount) {
                throw new ConcurrentModificationException();
            }
            modCount++;
        }

        return anyToRemove;
    }

 

//将list中的元素按照传进去的函数转换成另一个元素

 @Override
    @SuppressWarnings("unchecked")
    public void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final int expectedModCount = modCount;
        final int size = this.size;
        for (int i=0; modCount == expectedModCount && i < size; i++) {
            elementData[i] = operator.apply((E) elementData[i]);
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }

//调用Arrays里面的方法去对内部数组排序
    @Override
    @SuppressWarnings("unchecked")
    public void sort(Comparator<? super E> c) {
        final int expectedModCount = modCount;
        Arrays.sort((E[]) elementData, 0, size, c);
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }
}

 

posted @ 2021-08-17 23:27  菜逼黑  阅读(17)  评论(0编辑  收藏  举报