ArrayList父类关系
ArrayList继承AbstractList抽象类,实现了List,RandomAccess,Cloneable,Seriazable四个接口。
RandomAccess,Cloneable,Seriazable是标记接口,本身没有内容。
RandomAccess用于标明实现该接口的List支持快速随机访问,主要目的是使算法能够在随机和顺序访问的list中表现的更加高效。
Cloneable 用于允许使用clone()方法进行克隆。
Seriazable 用于类可以实现序列化。
ArrayList成员变量
ArrayList本身有七个成员变量,还有AbstractList的成员变量 modCount。
1 serialVersionUID
2 DEFAULT_CAPACITY
3 EMPTY_ELEMENTDATA
4 DEFALUTCAPACITY_EMPTY_ELEMENTDATA
5 elementData
6 size
7 MAX_ARRAY_SIZE
serialVersionUID:序列化id,私有静态不可变长整型(private static final long)
DEFAULT_CAPACITY:默认ArrayList大小,默认大小为10, 私有静态不可变整型(private static final int)。
EMPTY_ELEMENTDATA:空实例,默认为{},私有静态不可变对象数组(private static final Object[]。构造方法带参的时候,赋值给elementData,即ArrayList(int initialCapacity)和ArrayList(Collection<? Extend E> c)。
DEFAULTCAPACITY_EMPTY_ELEMENTDATA:采用ArrayList默认大小10创建的空实例,为{}。与EMPTY_ELEMENTDATA区别就是,后者知道初始化大小,前者初始化大小固定为10。
elementData:对象数组,用来存储真正的数据,protected transient Object[],transient无法被序列化。
Size:Arraylist包含元素数量,不是ArrayList的长度,私有整形(private int)。
modCount:protected transien int,初始化大小为0,修改ArrayList的次数。
MAX_ARRAY_SIZE:ArrayList最大长度,为Integer最大值减去8。私有静态不可变整型(private static final int)。
ArrayList构造方法
1 public ArrayList(int initialCapacity)
如果initialCapacity大于0,根据给定的列表大小,创建一个指定大小的列表。
如果initialCapacity等于0,则将EMPTY_ELEMENTDATA空列表赋值给elementData。
如果initialCapacity小于0,则抛出IllegalArgumentException参数非法异常。
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
2 public ArryList()
将DEFAULTCAPACITY_EMPTY_ELEMENTDATA空列表赋值给elementData。
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
3 public ArrayList(Collection<? Extends E> c)
根据给定的集合创建列表。
将给定的集合数组化,即调用集合的toArray()方法。
将elementData的长度赋值给size。
如果size不大于0,将EPMTY_ELEMENTDATA赋值给elementData。
如果size大于0,判断elementData是不是Object[]类型,是则调用Arrays.copyOf(elementData,size,Object[].class)赋值给elementData。
ArrayList调用Arrays的copyOf方法,
根据size创建一个Object数组,再调用
System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength)),original为elementData,copy即为新建的Object[],newLength为size。
System.arraycopy(Object src,int srcPos,Object dest,int destPos,int length)方法5个参数分别为要拷贝的原始数据,原始数据拷贝的起始序号,目标数据,目标数据的起始序号,要拷贝的长度。
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;
}
}
Arrays的copy方法
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;
}
ArrayList成员方法
Public Void trimToSize():移除未使用已申请内存的元素
增加modcount。
如果size比element长度小
当size为0时,element就赋值为EMPTY_ELEMENTDATA;
否则就使用Arrays.copy拷贝数组返回,Arrays.copy(elementData,size)。
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
Public Void ensureCapacity(int minCapacity):以minCapacity作为ArrayList最小容量扩展。
如果elementData是一个空列表,则minExpand为ArrayList默认大小,否则为0。
如果minCapacity大于minExpand,则需要扩展ArrayList。调用ensureExplicitCapacity(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);
}
}
Private void ensureCapacityInternal(int minCapacity): 以minCapacity作为ArrayList最小容量扩展
如果elementData为空列表,minCapacity重新赋值为DEFAULT_CAPACITY和minCapacity中的最大值。再调用ensureExplicitCapacity(int minCapacity)方法。
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
Private Void ensureExplicitCapacity(int minCapacity):扩展ArrarList。
增加修改次数modConut,如果minCapacity大于elementData的长度,则需要扩展,调用grow(int minCapacity)方法。
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
Private Void grow(int minCapacity):根据minCapacity扩展ArrayList
oldCapacity用来存储原始elementData大小。
newCapacity用来存储新elementData大,为oldCapacity+oldCapacity>>1,即加上原来的一半,>>1位运算右移,原来数据的一半。
如果newCapacity小于minCapacity,则将newCapacity赋值为minCapacity。
如果newCapacity大于MAX_ARRAY_SIZE,则将newCapacity赋值为hugeCapacity(int minCapacity)返回值。
最后elementData为Arrays.copyof(elementData,newCapacity)。
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);
}
Private static int hugeCapacity(int minCapacity):返回list最大容量
如果minCapacity小于0,抛出OutOfMemoryError。
如果minCapacity大于MAX_ARRAY_SIZE,则返回Integer.MAX_VALUE,否则返回MAX_ARRAY_SIZE。
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
Public int size():返回ArrayList大小。
public int size() {
return size;
}
Public Boolean isEmpty():判断ArrayList是否为空。
public boolean isEmpty() {
return size == 0;
}
Public Boolean contains(Object object):返回ArrayList是否包含指定对象
调用indexOf(Object object)方法,返回是否大于等于0。
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
Public int indexOf(Object o):返回指定对象在ArrayList中第一次出现的下标
下标从0开始。
如果o是null,则循环ArrayList循环从0开始,判断elementData[i]==null(null元素不能使用equals方法,返回空指针异常)找到返回i;
否则o.equals(elementData[i]),相等返回i。
如果没找到相同对象,返回-1。
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;
}
Public int lastIndexOf(Object o):返回指定对象在ArrayList中最后一次出现的下标。
下标从size-1开始。其他和indexOf方法相似,找到返回下标,找不到返回-1。
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;
}
Public Object clone():实现ArrayList的浅拷贝。
super.clone()调用Object的clone方法,克隆ArrayList,赋值给ArrayList<?> v。再调用Arrays.copyOf(elementData,size)赋值给v.elementData,并把v的修改次数modCount置为0。
返回v。
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);
}
}
public Object[] toArray():将elementData数据以Object数组形式返回
调用Arrays.copyOf(elementData,size)。
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
public <T> T[] toArray(T[] a):将elementData以指定参数的类型返回数组。
如果a.length小于elementData的size,返回(T[]) Arrays.copyOf(elementData, size, a.getClass())。
如果a.length不小于elementData的size,则直接调用System.arraycopy(elementData,0,a,0,size);
如果a.length大于elementData的size,则a[size]=null。
@SuppressWarnings("unchecked")
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;
}
E elementData(int index):返回指定下标的元素。
不对外暴露,返回elementData[index]。
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
public E get(int index):真正对外暴露的返回指定下标的元素的方法。
首先调用rangeCheck(int index)方法,判断index是否越界。
如果index不小于size,则抛出IndexOutOfBoundsException(outOfBoundsMsg(index))异常;
否则调用E elementData方法返回指定下标元素。
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
public E set(int index, E element):对指定下标设值。
首先调用rangeCheck(int index)方法,判断index是否越界。
如果index不小于size,则抛出IndexOutOfBoundsException(outOfBoundsMsg(index))异常;
否则调用E elementData方法返回指定下标原始元素,再将指定新元素赋值给指定下标,返回原始元素。
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
public boolean add(E e):增加元素。
调用ensureCapacityInternal方法,判断数组容量是否够,不够就扩展。elementData[size++]=e;如果没有异常返回true。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
public void add(int index, E element):指定下标添加元素。
首先调用rangeCheckForAdd(int index),判断index是否大于size或者小于0。调用ensureCapacityInternal方法,判断数组容量是否够,不够就扩展。再调用System.arraycopy(elementData,index,elementData,index+1,size-index);elementData[index]=element;size++。
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++;
}
public E remove(int index):根据下标移除元素。
首先调用rangeCheck方法,判断index是否越界。
增加modCount,存储下标原始数据oldValue。
numMoved为需要移动的数据数量,numMoved=size-index-1。
如果numMoved大于0,说明需要移动,调用System.arraycopy(elementData,index+1,elementData,index,numMoved);
再将elementData最后一个元素赋值为null,利于gc回收。
elementData[--size]=null,返回原始数据。
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;
}
public boolean remove(Object o):根据指定对象移除元素。
如果o为null,循环list,如果list中元素==null,则调用fastRemove(int index)方法,移除元素,返回true;
否则循环list,使用equals方法比对元素,如果equals返回true,则调用fastRemove(int index)方法移除元素,返回true。
如果没有找到相同元素,返回false。
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。
numMoved为需要移动的数据数量,numMoved=size-index-1。
如果numMoved大于0,说明需要移动,调用System.arraycopy(elementData,index+1,elementData,index,numMoved);
再将elementData最后一个元素赋值为null,利于gc回收,elementData[--size]=null。
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
}
public void clear():移除所有list元素。
增加modCount。
所有elementData的元素都赋值为null,循环根据size,最后将size赋值为0。
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
public boolean addAll(Collection<? extends E> c):添加集合列表。
首先将集合c通过toArray()方法,转成Object对象数组a。
numNew为增加的长度即为a.length。
调用ensureCapacityInternal(size+numNew)确保list长度。
调用System.arrayCopy(a,0,elementData,size,numNew)拷贝数组。
size+=numNew,返回numNew!=0。
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;
}
public boolean addAll(int index, Collection<? extends E> c):指定下标位置添加集合列表。
首先调用rangeCheckForAdd(int index),判断index是否大于size或者小于0。将集合c通过toArray()方法,转成Object对象数组a。
numNew为增加的长度即为a.length,调用ensureCapacityInternal(size+numNew), numMoved=size-index。
如果numMoved大于0,说明需要移动。
调用System.arraycopy(elementData,index+1,elementData,index+numNew,numMoved)移动list,腾出位置。
再调用System.arraycopy(a,0,elementData,index,numNew);size+=numNew,返回numNew!=0。
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;
}
protected void removeRange(int fromIndex, int toIndex):范围删除元素。
ModCount++,numMoved为size-toIndex。
调用System.arraycopy(element,toIndex,elementData,fromIndex,numMoves)。
NewSize=size-(toIndex-fromIndex),循环list,循环从newSize到size结束,elementData[i]赋值为null,利于gc回收,最后size赋值为newSize。
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;
}
private void rangeCheck(int index):判断index是否越界。
index不小于size时,抛出IndexOutOfBoundsException(outOfBoundsMsg(index));
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index):添加元素时判断index是否越界。
index大于size或者index小于0时,抛出IndexOutOfBoundsException(outOfBoundsMsg(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。
public boolean removeAll(Collection<?> c):删除list中存在于集合中元素。
首先调用Objects.requiredNonNull(c)方法,判断c是否为null,返回batchRemove(c,false)。
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
public boolean retainAll(Collection<?> c):保留list中存在于集合c中元素,即删除不在c中元素。
首先调用Objects.requiredNonNull(c)方法,判断c是否为null,返回batchRemove(c,true)。
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement):根据条件删除或保留数组元素。
complement来决定是删除存在于c中的元素,还是删除不存在于c中的元素,complement为true,删除不存在的元素,否则为false删除存在元素。
定义一个final Object[] elementData赋值为this.elementData。
定义r=0,w=0,r用来循环,w作为符合条件元素的下标位置。
定义boolean modified,初始化为false,默认没有修改。
try中用r来作为循环的条件,c.contains(elementData[r])==complement,如果满足,elementData[w++]=elementData[r]。
finally 如果非正常结束,即r!=size,调用System.arraycopy(elementData,r,elementData,w,size-r),w+=size-r。
如果w!=size,则下标从w开始,到size-1结束,list元素赋值为null,modCount+=size-w,size=w,modified=true。
最后返回modified。
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;
}
private void writeObject(java.io.ObjectOutputStream s):将list写入流中,即序列化。
定义一个expectedModCount,用来存储modCount,防止并发的时候其他线程修改了modCount产生异常。
s.defaultWriteObject(),s.writeInt(size) 写入list大小。
再通过循环调用s.writeObject写入元素。
如果expectedModCount!=modCount则说明被其他线程修改了,抛出ConcurrentModificationException()。
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();
}
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException:反序列化。
elementData赋值为EMPTY_ELEMENTDATA。
s.defaultReadObject(),s.readInt()。
如果size大于0,ensureCapacityInternal(size);Object[] a = elementData;
再循环s.readObject()。
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
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<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();
public ListIterator<E> listIterator(int index):从list下标从index开始返回list迭代器。
如果index<0或者index>size抛出IndexOutOfBoundsException("Index: "+index);否则返回ListItr(index)。
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
public ListIterator<E> listIterator():返回list迭代器。
返回ListItr(0);
public ListIterator<E> listIterator() {
return new ListItr(0);
}
public Iterator<E> iterator():返回迭代器。
返回Itr()。
public Iterator<E> iterator() {
return new Itr();
}
public List<E> subList(int fromIndex, int toIndex):分割list,返回从fromIndex到toIndex下标的list。
首先调用subListRangeCheck(fromIndex, toIndex, size),判断fromIndex,toIndex是否越界。
最后返回new SubList(this, 0, fromIndex, toIndex)。
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):判断fromIndex和toIndex是否符合规则。
如果fromIndex<0抛出IndexOutOfBoundsException("fromIndex = " + fromIndex)。如果toIndex>size,则抛出IndexOutOfBoundsException("toIndex = " + toIndex)。如果fromIndex>toIndex,则抛出IllegalArgumentException("fromIndex(" + fromIndex +") > toIndex(" + 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 + ")");
}
public void forEach(Consumer<? super E> action):对list元素根据action函数式循环。
先判断action是否为空。
再记录modCount赋值给expectedModCount,final int size=this.size,final E[] elementData=(E[])this.elementData。
根据size循环list,循环条件为expectedModCount==modCount&&i<index,防止并发的时候,modCount被其他线程修改。
循环体中,action.accept(elementData[i])。
最后判断modCount==expectedModCount,不等的话抛出异常ConcurrentModificationException();
@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();
}
}
public Spliterator<E> spliterator():返回一个ArrayListSpliterator<>(this, 0, -1, 0)。
@Override
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
public boolean removeIf(Predicate<? super E> filter):根据Predicate条件删除list元素。
判断filter是否为空。
removeCount为删除元素数量,初始值为0,。
removeSet为要删除的BitSet,初始化为new BitSet(size)。
记录modCount赋值给expectedModCount,final int size=this.size。
根据size循环list,循环条件为expectedModCount==modCount&&i<index,防止并发的时候,modCount被其他线程修改。
final E element为elementData[i],如果element满足filter条件,removeSet.set(i),removeCount++。
判断modCount==expectedModCount,不等的话抛出异常ConcurrentModificationException()。
final boolean anyToRemove为是否有元素删除标志,赋值为removeCount>0。如果anyToRemove为true,newSize为size-removeCount,再进行循环。
循环条件为i<size&&j<newSize,
i=removeSet.nextClearBit(i),nextClearBit为返回下一个false位置,elementData[j]=elementData[i],赋值不满足条件元素,即不需要删除的元素。
再循环将移除元素的位置置为null,利于gc回收,循环条件为k=newSize,k<newSize。
将size赋值为newSize。
判断modCount==expectedModCount,不等的话抛出异常ConcurrentModificationException()。
最后modCount++,返回anyToRemove。
@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;
}
public void replaceAll(UnaryOperator<E> operator):根据UnaryOperator对象操作list。
先判断operator是否为空,再记录modCount赋值给expectedModCount,final int size=this.size。
根据size循环list,循环条件为expectedModCount==modCount&&i<index,防止并发的时候,modCount被其他线程修改。
循环体中,elementData[i] = operator.apply((E) elementData[i])。
最后判断modCount==expectedModCount,不等的话抛出异常ConcurrentModificationException();modCount++。
@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++;
}
public void sort(Comparator<? super E> c):排序。
记录modCount赋值给expectedModCount。
再调用Arrays.sort(elementData,0,size,c)。
最后判断modCount==expectedModCount,不等的话抛出异常ConcurrentModificationException();modCount++。
@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++;
}
内部类
private class Itr implements Iterator<E>
成员变量
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<E> 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<E> implements Spliterator<E>
成员变量,private final ArrayList<E> list 用来存储list;private int index 存储起始下标;private int fence 结束下标; private int expectedModCount 修改次数modCount;
构造方法
ArrayListSpliterator(ArrayList<E> list, int origin, int fence,int expectedModCount)
成员方法:
private int getFence():获取fence。定义int hi ArrayList<E>lst。如果hi=fence 不小于0,说明fence已经赋值过了,返回hi;否则判断lst=list 是否为null,如果是hi=fence=0,否则expectedModCount=lst.modCount,hi=fence=lst.size。
public ArrayListSpliterator<E> 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。