List--ArrayList-源码理解

一、继承关系
public class ArrayList<E> extends AbstractList<E>  implements List<E>, RandomAccess, Cloneable, java.io.Serializable
1.ArrayList父类关系
继承AbstractList抽象类,
实现了List,RandomAccess,Cloneable,Seriazable四个接口。
RandomAccess,Cloneable,Seriazable是标记接口,本身没有内容。
1.1RandomAccess
用于标明实现该接口的List支持快速随机访问,主要目的是使算法能够在随机和顺序访问的list中表现的更加高效。
1.2 Cloneable
用于允许使用clone()方法进行克隆。
1.3 Seriazable
用于类可以实现序列化。
二、常量
//初始化数组长度,默认10,用于构造函数使用
private static final int DEFAULT_CAPACITY = 10;
/** 空实例,默认为{},私有静态不可变对象数组(private static final Object[]。构造方法带参的时候,赋值给elementData,即ArrayList(int initialCapacity)和ArrayList(Collection<? Extend E> c) */
private static final Object[] EMPTY_ELEMENTDATA = {};
/** 采用ArrayList默认大小10创建的空实例,为{}。与EMPTY_ELEMENTDATA区别就是,后者知道初始化大小,前者初始化大小固定为10。*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//对象数组,用来存储真正的数据,protected transient Object[],transient无法被序列化。
transient Object[] elementData;
//Arraylist包含元素数量,不是ArrayList的长度,私有整形(private int)。
private int size;
//来自于父类AbstractList,用于记录操作ArrayList次数
transient modCount;
//ArrayList最大长度,为Integer最大值减去8。私有静态不可变整型(private static final int)。
private static final int MAX_ARRAY_SIZE;
三、构造函数
1.public ArrayList(int initialCapacity)
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);   
                }
  }

如果initialCapacity大于0,根据给定的列表大小,创建一个指定大小的列表。
如果initialCapacity等于0,则将EMPTY_ELEMENTDATA空列表赋值给elementData。
如果initialCapacity小于0,则抛出IllegalArgumentException参数非法异常。

1.2 public ArrayList()
public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
 }

无构造参数的构造器方法,数组为空,长度为10,是在第一次添加元素时设置长度为10;

1.3 public ArrayList(Collection<? extends E> c)
    public ArrayList(Collection<? extends E> c) {    
        elementData = c.toArray();  
        if ((size = elementData.length) != 0) {      
        // c.toArray might (incorrectly) not return Object[] (see 6260652)    
        if (elementData.getClass() != Object[].class)           
                elementData =   Arrays.copyOf(elementData, size, Object[].class);  
    } else {       
       // replace with empty array.       
       this.elementData = EMPTY_ELEMENTDATA;    
       }
   }

构造参数是集合数组,将其赋值给elementData,使用toArray方法;
将赋值之后的elementData的长度赋值于size,并判断是否为0;
为0则将EMPTY_ELEMENTDATA空数组赋值给elementData;
不为0,则要判断toArry返回是否是Object类型,不是则需调用
Arrays的copyOf方法,如下:

public static <T,U> T[] copyOf(U[] original, int newLength, 
Class<? extends T[]> newType) {  
        @SuppressWarnings("unchecked")  
            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;
}
四、成员方法
4.1 trimToSize()
    public void trimToSize() {   
        modCount++;
        if (size < elementData.length) {
            elementData = (size == 0)         
            ? EMPTY_ELEMENTDATA 
            : Arrays.copyOf(elementData, size); 
         }
    }

用于清除未使用但实际存在的数据:
modCount自增;
size与当前数组数量比较,如果小于当前数组数量,若size=0,则elementData置为空,若不是则,调用Arrays.copyOf方法拷贝数组返回。

4.2 public void ensureCapacity(int minCapacity)
public void ensureCapacity(int minCapacity) {   
            int minExpand = (elementData != 
                DEFAULTCAPACITY_EMPTY_ELEMENTDATA)    
            // any size if not default element table    
            ? 0       
           // larger than default for default empty table. It's already       
          // supposed to be at default size.  
          : DEFAULT_CAPACITY; 
          if (minCapacity > minExpand) {   
                    ensureExplicitCapacity(minCapacity);   
             }
    }

该方法是以minCapacity作为ArrayList最小的扩展容量;
首先判断当前elementData是否为空,为空时,minExpand=0;
不为空时则设置为默认数组长度10;
当传参minCapacity大于minExpand,调用ensureExplicitCapacity扩展数组容量

    private void ensureExplicitCapacity(int minCapacity) {  
    modCount++;   
    // overflow-conscious code  
    if (minCapacity - elementData.length > 0)   
    grow(minCapacity);
   }

ensureExplicitCapacity:当最小扩展容量大于当前数组容量时,调用grow方法扩展容量

4.3 calculateCapacity(Object[] elementData, int minCapacity)
private static int calculateCapacity(Object[] elementData, int minCapacity) { 
      if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  
           return Math.max(DEFAULT_CAPACITY, minCapacity);   
         }
        return minCapacity;
  }

calculateCapacity: 当elementData为空时,比较minCapacity和默认容量大小,返回较大的值为扩展容量;如果不为空时,返回minCapacity作为扩展容量;

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

ensureCapacityInternal: 以minCapacity作为最小容量扩展,首先调用calculateCapacity 方法,获取扩展容量,在调用ensureExplicitCapacity 扩展数组容量

4.5 ensureExplicitCapacity(int minCapacity)
private void ensureExplicitCapacity(int minCapacity) {  
        modCount++;   
// overflow-conscious code  
        if (minCapacity - elementData.length > 0)    
            grow(minCapacity;
    }

*ensureExplicitCapacity: 修改次数modCount自增,判断minCapacity是否大于当前数组长度,true则调用 grow(minCapacity) 扩展数组容量。

4.6 grow(int minCapacity)
private void grow(int minCapacity) {    
    // overflow-conscious code  
        int oldCapacity = elementData.length; 
        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);}

grow: 扩展数组容量,首先将原先数组扩展至1.5倍,minCapacity与扩展后的数组容量newCapacity大小比较,如果newCapacity小于minCapacity,则将minCapacity赋值给newCapacity;接着newCapacity与MAX_ARRAY_SIZE(Integer最大值-8)比较大小,如果大于MAX_ARRAY_SIZE,则调用hugeCapacity 方法,最终调用Arrays.copyOf 扩展当前数组

4.7 hugeCapacity(int minCapacity)
   private static int hugeCapacity(int minCapacity) {    
            if (minCapacity < 0)
            // overflow    
            throw new OutOfMemoryError();   
            return (minCapacity > MAX_ARRAY_SIZE) ?   
            Integer.MAX_VALUE :  MAX_ARRAY_SIZE;
      }

hugeCapacity: 该方法返回list的最大容量;
如果minCapacity小于0,抛出OutOfMemoryError。如果minCapacity大于MAX_ARRAY_SIZE,则返回Integer.MAX_VALUE,否则返回MAX_ARRAY_SIZE。

4.7 size():返回list长度
public int size() {  
    return size;
    }
4.8 isEmpty(): 判断list长度是否为空
public boolean isEmpty() {  
    return size == 0;
  }
4.9 contains(Object o)
public boolean contains(Object o) { 
        return indexOf(o) >= 0;
    }

判断list是否包含某对象,调用indexOf方法

4.10 indexOf(Object o)
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;
   }

如果传参对象为null则遍历当前list(从0开始比较),返回null对象所在list的位置下标;如果不为弄,也是遍历list用equals方法比较两个对象是否相等,如果都没有获取对象的下标,则返回-1。

4.11 lastIndexOf(Object o)
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;
}

与上述indexOf判断逻辑一直,只不过遍历顺序从size-1开始,获取某对象的在list最后出现的下标。

4.12 public Object clone()
public Object clone() {   
    try {    
        ArrayList<?> v = (ArrayList<?>) super.clone();    
        v.elementData = Arrays.copyOf(elementData, size); 
        v.modCount = 0;   
        return v;  
        } catch (CloneNotSupportedException e) {   
        // this shouldn't happen, since we are Cloneable     
        throw new InternalError(e);  
        }
   }

实现list浅拷贝,并将修改字段modCount置为0,并返回v.

4.13 Object[] toArray():将elementData数据以Object数组形式返回
public Object[] toArray() {  
        return Arrays.copyOf(elementData, size);
  }
4.14 T[] toArray(T[] a)
public <T> T[] toArray(T[] a) { 
        if (a.length < size)    
        // Make a new array of a's runtime type, but my  contents:    
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());  
            System.arraycopy(elementData, 0, a, 0, size); 
        if (a.length > size)  
              a[size] = null;   
            return a;
}

判断要转化的数组长度是否大于当前list长度,如果小与size,调用Arrays.copyOf直接返回以T对象类型的数组;
若不小于size,先调用System.arraycopy方法将其list的elementData数据以T对象类型的数组返回;
若a.length大于elementData的size,则a[size]=null,即超出的部分为null。

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

根据index下标获取list的值:首先会判断index是否已超过当前list的size,随后返回值

rangeCheck(index):判断是否超出边界
    private void rangeCheck(int index) {   
    if (index >= size) 
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  }
elementData(int index):根据下标返回值
@SuppressWarnings("unchecked")
    E elementData(int index) {  
        return (E) elementData[index];
}
4.16 E set(int index, E element):设置某一下标的数据
public E set(int index, E element) {
        rangeCheck(index);   
        E oldValue = elementData(index);   
        elementData[index] = element;   
        return oldValue;
}

判断index是否超出list边界,获取该下标的原先的值,并将element赋值到该下标下,并将原先的值返回。

4.17 boolean add(E e):添加值
public boolean add(E e) {  
    ensureCapacityInternal(size + 1);  
// Increments modCount!! 
    elementData[size++] = e;   
    return true;}

调用ensureCapacityInternal方法,判断数组容量是否够,不够就扩展。elementData[size++]=e;如果没有异常返回true。

4.18 add(int index, E element) :指定下标下添加值
public void add(int index, E element) {  
    rangeCheckForAdd(index);    
    ensureCapacityInternal(size + 1); 
    // Increments modCount!!  
    System.arraycopy(elementData, index, elementData, index + 1,  size - index);  
     elementData[index] = element;   
     size++;
        }

添加值到指定下标:首先判断是否越界,判断是否扩展容量,调用System.arraycopy方法将elementData以index后面的数据从下标index开始向后移一位,并将element赋值在index下标的位置上。

4.19 remove(int index):移除指定下标的数据
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; // clear to let GC do its work    
        return oldValue;
}

首先判断是否超出边界,modCount自增,获取该下标的原始数据,计算出需要移动的个数numMoved,如果大于0,则调用System.arraycopy将index+1以后的数据向前移一位;
elementData最后一位置为null,(垃圾回收机制起作用时会将其清除内存),并返回原始数据。

4.20 remove(Object o):移除指定元素
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;
}

判断移除的元素类型是否为null,遍历list判断是否有指定元素,有则调用fastRemove移除指定元素

4.21 fastRemove(int index):快速移除指定下标元素
private void fastRemove(int index) {     
        modCount++;  
        int numMoved = size - index - 1; 
        if (numMoved > 0)        
            System.arraycopy(elementData, index+1, elementData, index, numMoved); 
            elementData[--size] = null; 
// clear to let GC do its work}

modCount自增,计算是否移动数据个数,若有调用System.arraycopy方法将index+1以后的数据向前移一位。

4.22 clear() :全清除
public void clear() { 
    modCount++;  
// clear to let GC do its work  
    for (int i = 0; i < size; i++)   
     elementData[i] = null; 
        size = 0;
}

遍历list,设置为null。等待垃圾回收。

4.23 boolean addAll(Collection<? extends E> c):添加一组集合
public boolean addAll(Collection<? extends E> c) {   
    Object[] a = c.toArray(); 
    int numNew = a.length;  
    ensureCapacityInternal(size + numNew); 
    // Increments modCount  
    System.arraycopy(a, 0, elementData, size, numNew);  
    size += numNew;  
    return numNew != 0
}

通过集合c的toArray方法获取对象数组a,获得数组a的长度,确保当前list的长度,调用System.arraycopy方法将a数据赋值到list中,size长度增加了a的长度。

4.24 boolean addAll(int index, Collection<? extends E> c) :添加一组集合到指定下标
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;
}

判断是否下标是否超出边界,将集合c转换成对象数组a,确保list长度足够容纳添加数据,计算出要要移动的个数和位数,并将其拷贝至list中。

4.25 protected void removeRange(int fromIndex, int toIndex) :移除区间范围内的数据
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;
  }

自增修改次数字段,计算要移动的个数和位数,调用System.arraycopy方法将下标toIndex后面的数据移至下标fromIndex位置,计算list移除后的长度,将多余的数据置为null。
设置list的移除后的长度给size。

4.26 removeAll(Collection<?> c) :移除某一集合数据
public boolean removeAll(Collection<?> c) { 
   Objects.requireNonNull(c);  
   return batchRemove(c, false);
}

首先判断集合c是否为空,调用batchRemove方法移除集合c数据。

4.27 retainAll(Collection<?> c)
public boolean retainAll(Collection<?> c) {  
    Objects.requireNonNull(c);  
    return batchRemove(c, true);
}

保留list中存在于集合c中元素,即删除不在c中元素。

4.28 boolean batchRemove(Collection<?> c, boolean complement):删除或保留集合的操作
private boolean batchRemove(Collection<?> c, boolean complement) {    
        final Object[] elementData = this.elementData; 
        int r = 0, w = 0;   
        boolean modified = false; 
    try {     
        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. 
        if (r != size) {    
        System.arraycopy(elementData, r,  elementData, w,      size - r);  
        w += size - r;    
    }      
        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;
}

complement用来表示是移除c集合中的元素还是只保留c集合中的元素,true只保留集合c元素,false移除集合c元素,遍历list,判断集合c元素是否在list中,并与complement做是否相等判断,当complement为false时,即删除list中包含集合c的元素,elementData存储未在集合c的list元素;当complement为true时,即只保留list中包含集合c的元素,elementData存储在集合clist元素;如果非正常结束即r!=size,则调用System.arraycopy方法将r之后未曾遍历数据拷贝至list下标w之后,保证从0到w下标的数据是符合条件的,并计算出list的执行完该方法后长度;当w != size时,即表示需要操作list数据,移除下标w之后的数据 ,记录操作list的次数,并重置list长度,返回修改标识。

4.29 private void writeObject(java.io.ObjectOutputStream s) :将list写入流中,并序列化
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(); 
    }
}

获取当前list的操作次数,防止并发时其他线程操作此list从而引起异常, s.defaultWriteObject();   s.writeInt(size); 写入list大小;遍历list将其数据写入s中。

4.30 private void readObject(java.io.ObjectInputStream s) :反序列化,读出流中list
private void readObject(java.io.ObjectInputStream s)    throws java.io.IOException, ClassNotFoundException {   
        elementData = EMPTY_ELEMENTDATA; 
    // Read in size, and any hidden stuff
        s.defaultReadObject();  
    // Read in capacity   
        s.readInt(); // ignored  
        if (size > 0) {     
    // be like clone(), allocate array based upon size not capacity      
        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();    
        }  
    }
}

elementData设置为EMPTY_ELEMENTDATA, s.defaultReadObject(); s.readInt();
如果list的size大于0,调用calculateCapacity方法获取设置list的容量,并调ensureCapacityInternal方法确保list有足够的容量,
循环s.readObject()。

--------------------------------序列化与反序列化-----------------------------------------------

        ArrayList<String> list = new ArrayList();
         ObjectOutputStream o=new ObjectOutputStream(new FileOutputStream("1.txt"));
       o.writeObject(list); 
       ObjectInputStream in=new ObjectInputStream(new FileInputStream("1.txt"));
       ArrayList<String> x= (ArrayList<String>) in.readObject();


4.31 ListIterator listIterator(int index):从list下标从index开始返回list迭代器
public ListIterator<E> listIterator(int index) {  
        if (index < 0 || index > size)    
             throw new IndexOutOfBoundsException("Index: "+index);  
        return new ListItr(index);
}

如果下标超过list的长度或为负值,抛出IndexOutOfBoundsException异常,否则返回从index以后的list迭代器ListItr(index)。

4.32 ListIterator listIterator():返回list迭代器
public ListIterator<E> listIterator() { 
        return new ListItr(0);
   }

返回ListItr(0)。

4.33 Iterator iterator() :返回迭代器
public Iterator<E> iterator() {
        return new Itr();
}
4.34 List subList(int fromIndex, int toIndex):分割list,返回从fromIndex到toIndex下标的list。
public List<E> subList(int fromIndex, int toIndex) {  
        subListRangeCheck(fromIndex, toIndex, size);  
        return new SubList(this, 0, fromIndex, toIndex);
}

调用subListRangeCheck方法校验截取区间是否在list内,

4.35 static void subListRangeCheck(int fromIndex, int toIndex, int size):校验区间(fromIndex,toIndex)是否在size内
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 + ")");
}
4.36 void forEach(Consumer<? super E> action):对list进行函数式循环(重写Iterable接口中的方法)
@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(); 
        }
    }

通过Objects.requireNonNull方法判断action是否为空,获取当前list的修改次数(用于)判断list是否被其他线程进行过修改,遍历 list,输入到action.accept中。

4.37 boolean removeIf(Predicate<? super E> filter):根据Predicate条件删除list元素
@Override
public boolean removeIf(Predicate<? super E> filter) {        
        Objects.requireNonNull(filter);  
        // figure out which elements are to be removed  
        // any exception thrown from the filter predicate at this stage   
        // will leave the collection unmodified   
        int removeCount = 0;  
        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();
    }  
    // shift surviving elements left over the spaces left by removed elements  
        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 = removeSet.nextClearBit(i);    
                    elementData[j] = elementData[i];   
}     
        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;
}

判断Predicate函数式的filter非空,设置移除个数,声明removeSet用于存储满足条件的下标的位值,获取当前list修改次数参数和list长度,遍历list获取符合条件的list下标,并存储至removeSet(将指定索引处的位设置为 true。),同时校验该操作时list不被其他线程修改。anyToRemove标识是否有满足移除条件,true标识有需要移除的元素,false标识无需移除。newSize表示移除后的list长度,通过nextClearBit(i) 为返回下一个false位置,即表示下标i是无需移除的元素,并将请i所在的元素赋值给下标k上。循环结束之后,在循环list下标newSize之后的元素,设置为null。最后判断此次操作是否有其他线程对list进行修改,modCount自增,list长度设置为newSize。

4.38 public Spliterator spliterator():返回一个ArrayListSpliterator<>(this, 0, -1, 0)
@Override
    public Spliterator<E> spliterator() {
        return new ArrayListSpliterator<>(this, 0, -1, 0);
    }
4.39 replaceAll(UnaryOperator operator):根据UnaryOperator对象操作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++;
    }

先判断operator是否为空,再记录modCount赋值给expectedModCount,final int size=this.size。根据size循环list,循环条件expectedModCountmodCount&&i<index,防止并发的时候,modCount被其他线程修改。循环体中,elementData[i] = operator.apply((E) elementData[i])。最后判断modCountexpectedModCount,不等的话抛出异常ConcurrentModificationException();modCount++。

4.40 sort(Comparator<? super E> c):根据比较器对list进行排序
@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++;
    }

记录modCount赋值给expectedModCount。
再调用Arrays.sort(elementData,0,size,c)。
最后判断modCount==expectedModCount,不等的话抛出异常ConcurrentModificationException();modCount++。

五、内部类

private class Itr implements Iterator
成员变量

cursor:下一个返回的下标。
LastRet:最后返回的下标,初始化为-1。
****expectedModCount:记录modCount,防止并发造成的其他线程修改list,可以抛出异常。

成员方法

public boolean hasNext():判断是否还有下一个元素。
判断条件为cursor是否等于size。
public E next():返回下一个迭代器元素。
首先调用checkForComdification(),判断modConut是否被其他线程修改了。
I赋值为cursor,即原先开始下标,i如果不小于size,抛出NoSuchElementException()。
Object[] elementData赋值为ArrayList.this.elementData。
如果i不小于elementData.length,则抛出new ConcurrentModificationException()。Cursor=i+1,返回(E) elementData[lastRet = i],即返回elementData[i],又将i赋值给lastRet。
public void remove():删除上一次返回元素,即下标为lastRet。
判断lastRet是否小于0,如果小于0,抛出IllegalStateException()。
调用checkForComdification(),判断modConut是否被其他线程修改了。
try 调用ArrayList.this.remove(lastRet)方法,删除下标为lastRet元素,再将cursor指向lastRet坐标,lastRet重新赋值为-1, expectedModCount赋值为modCount,因为ArrayList.this.remove()方法会修改modCount。
Catch捕获IndexOutOfBoundsException异常,抛出ConcurrentModificationException()。
public void forEachRemaining(Consumer<? super E> consumer):根据consumer对list元素函数式操作。
先判断consumer是否为空,i等于cursor,size=ArrayList.this.size,如果i不小于size,抛出异常,elementData赋值为ArrayList.this.elementData,如果i不小于elementData.length,抛出异常。While循环条件为i不等于size,expectedModCount等于modCount,循环体内容为consumer.accept((E)elementData[i++]);循环结束,cursor=i+1,lastRet=i,最后调用checkForComdification(),判断list是否被其他线程修改了。
final void checkForComodification():判断list是否被其他线程修改了,判断条件为expectedModCount于modCount是否相等。

private class ListItr extends Itr implements ListIterator list迭代器
构造方法

ListItr(int index):super(),cursor=index。
public boolean hasPrevious():是否先前的元素,返回cursor!=0,即cursor不为0。
public int nextIndex():返回下一个元素的下标,返回cursor。
public int previousIndex():返回先前元素下标,返回cursor-1。
public E previous():返回前一个元素。调用checkForComdification()方法,判断list是否被其他线程修改了。I为前一元素下标,值为cursor-1,如果i<0抛出异常NoSuchElementException();elementData赋值为ArrayList.this.elementData,如果i不小于elementData.length,则抛出异常ConcurrentModificationException()。
Cursor=I,返回elementData[lastRet=i]。
public void set(E e):修改下标为lastRet元素的内容。先判断lastRet是否小于0,如果是抛出IllegalStateException();调用checkForComdification()方法,判断list是否被其他线程修改了,try 调用ArrayList.this.set(e),捕获IndexOutOfBoundsException,抛出ConcurrentModificationException异常。
public void add(E e):下一位置添加元素,即cursor位置添加元素。
调用checkForComdification()方法,判断list是否被其他线程修改了,try i=cursor,调用ArrayList.this.add(I,e),cursor指向下一元素,即cursor+1,lastRet置为-1,expectedModCount重新赋值为modCount,因为add方法会修改modCount,捕获IndexOutOfBoundsException,抛出ConcurrentModificationException异常。

static final class ArrayListSpliterator implements Spliterator
成员变量

private final ArrayList list 用来存储list;private int index 存储起始下标;
private int fence结束下标;
private int expectedModCount修改次数modCount;

构造方法

ArrayListSpliterator(ArrayList list, int origin, int fence,int expectedModCount)

成员方法:

private int getFence():获取fence。定义int hi ArrayListlst。如果hi=fence 不小于0,说明fence已经赋值过了,返回hi;否则判断lst=list 是否为null,如果是hi=fence=0,否则expectedModCount=lst.modCount,hi=fence=lst.size。
public ArrayListSpliterator trySplit():分割ArrayListSpliterator,取前半部分。
hi赋值为getFence(),lo=index,mid=(hi+lo)>>>1(无符号右移,即原来一半)。
如果lo不小于mid,则返回null,否则返回ArrayListSpliterator(list,lo,index=mid,expectedModCount)。
public boolean tryAdvance(Consumer<? super E> action):根据action对list 当前元素进行函数式操作。
先判断action是否为空,int h=getFence(),i=index,如果i<h,返回false;否则index指向下一个元素,e为list.elementData[i],action.accept(e),判断list.expectedModCount是否与expectedModCount相等,不等抛出异常ConcurrentModificationException异常。
public void forEachRemaining(Consumer<? super E> action):对list所有元素进行函数式操作。
I为index,hi为结束下标,mc为修改次数lst用来存储list,a[]为elementData。判断action是否为空。如果lst!=null&&a=lst.elementData!=null,执行下去,否则抛出异常ConcurrentModificationException()。执行如果hi=fence小于0,说明fence未被赋值过,则hi=lst.size,mc=lst.modCount,否则mc=expectedModCount。
如果i=index不小于0并且index=hi小于a.length,执行循环,action.accept()接受每一个元素。如果list.modCount==mc返回。
public long estimateSize():返回长度。(long)(getFence()-index)。
public int characteristics():返回Spliterator的ORDERED,SIZED,SUBSIZED。
返回Spliterator.ORDERED|Spliterator.SIZED|Spliterator.SUBSIZED。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值