一、继承关系
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。