/*** ArrayList源码分析,jdk版本为1.8.0_121*/
public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable {private static final long serialVersionUID = 8683452581122892189L;/*** 默认初始化容量*/
private static final int DEFAULT_CAPACITY = 10;/***
* 所有的容量为0的ArrayList对象来共享同一个空的数组*/
private static final Object[] EMPTY_ELEMENTDATA ={};/*** 使用new ArrayList()构造方法创建Arraylist对象的时候没有指定容量大小,此时该对象就使用这个空数组。
* 之所以要和上面的空数组区分开,是为了在加入第一个元素的时候来区分如何扩展数组容量。
* 如果在加入元素之前是EMPTY_ELEMENTDATA,则加入第一个元素的后容量扩展为1,
* 如果在加入元素之前是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,则加入第一个元素后容量扩展为DEFAULT_CAPACITY*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA ={};/*** 实际存储ArrayList元素的数组,该数组的大小就是当前ArrayList的容量
* 没有设计为私有是为了方便嵌套类的访问*/
transientObject[] elementData;/*** ArrayList 中元素的个数*/
private intsize;/*** 构建一个具有指定容量的空列表*/
public ArrayList(intinitialCapacity) {if (initialCapacity > 0) {this.elementData = newObject[initialCapacity];
}else if (initialCapacity == 0) {this.elementData =EMPTY_ELEMENTDATA;
}else{throw new IllegalArgumentException("Illegal Capacity: " +initialCapacity);
}
}/*** 构建一个空的ArrayList,并且加入第一个元素后,容量会扩展为DEFAULT_CAPACITY*/
publicArrayList() {this.elementData =DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}/*** 通过其他集合来构建ArrayList对象*/
public ArrayList(Collection extends E>c) {
elementData=c.toArray();if ((size = elementData.length) != 0) {if (elementData.getClass() != Object[].class)
elementData= Arrays.copyOf(elementData, size, Object[].class);
}else{this.elementData =EMPTY_ELEMENTDATA;
}
}/*** 将ArrayList的容量缩短为当前元素的个数*/
public voidtrimToSize() {
modCount++;if (size
elementData= (size == 0) ?EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size);
}
}/*** 这个是供外部调用,如果一次需要加入大量的元素的时候,可以手动调用此方法直接设置容量,避免多次自动扩容和数据复制
* 增加ArrayList对象的容量,来确保它至少能够容纳minCapacity个元素。
* 如果当前的ArrayList底层指向的不是DEFAULTCAPACITY_EMPTY_ELEMENTDATA数组且minCapacity要大于0那么就需要进一步确认是否扩容,看minCapacity是否大于当前容量
* 如果当前的ArrayList底层指向的是DEFAULTCAPACITY_EMPTY_ELEMENTDATA且需要扩容的值minCapacity大于10那么也需进一步确认是否扩容,通过后续要代码可知最终还是要扩容*/
public void ensureCapacity(intminCapacity) {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方法,供内部调用
* 如果当前对象指向的数组是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,则将DEFAULT_CAPACITY和minCapacity取最大值*/
private void ensureCapacityInternal(intminCapacity) {if (elementData ==DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity=Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}/*** 最后确认是否需要扩容,如果当前容量大于等于需要的容量,那就没有必要进行扩展*/
private void ensureExplicitCapacity(intminCapacity) {
modCount++;if (minCapacity - elementData.length > 0)
grow(minCapacity);
}/*** ArrayList最大容量*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;/*** 对ArrayList进行扩容,minCapacity是需要的最小容量
* 默认容量扩展为原来的1.5倍,如果1.5倍还不够就扩展到所需最小的容量minCapacity大小
* 如果minCapacity大于MAX_ARRAY_SIZE且还没有溢出,就将容量设置为Integer.MAX_VALUE*/
private void grow(intminCapacity) {//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(intminCapacity) {if (minCapacity < 0) //overflow
throw newOutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}/*** 返回元素的个数*/
public intsize() {returnsize;
}/*** 返回元素个数是否为0*/
public booleanisEmpty() {return size == 0;
}/*** 返回是否包含该元素*/
public booleancontains(Object o) {return indexOf(o) >= 0;
}/*** 判断对象o在ArrayList中第一次出现的位置,从前往后找*/
public intindexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++)if (elementData[i] == null)returni;
}else{for (int i = 0; i < size; i++)if(o.equals(elementData[i]))returni;
}return -1;
}/*** 判断对象o在ArrayList中最后出现的位置,从后往前找*/
public intlastIndexOf(Object o) {if (o == null) {for (int i = size - 1; i >= 0; i--)if (elementData[i] == null)returni;
}else{for (int i = size - 1; i >= 0; i--)if(o.equals(elementData[i]))returni;
}return -1;
}/*** 对现有的ArrayList进行克隆,但是里面的元素并没有被clone,是浅克隆*/
publicObject clone() {try{
ArrayList> v = (ArrayList>) super.clone();
v.elementData=Arrays.copyOf(elementData, size);
v.modCount= 0;returnv;
}catch(CloneNotSupportedException e) {//this shouldn't happen, since we are Cloneable
throw newInternalError(e);
}
}/*** 通过ArrayList得到一个数组*/
publicObject[] toArray() {returnArrays.copyOf(elementData, size);
}/*** 指定元素类型,通过ArrayList得到一个指定类型的数组*/@SuppressWarnings("unchecked")public T[] toArray(T[] a) {if (a.length
return(T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData,0, a, 0, size);if (a.length >size)
a[size]= null;returna;
}//Positional Access Operations
@SuppressWarnings("unchecked")
E elementData(intindex) {return(E) elementData[index];
}/*** 获取对应索引出的元素*/
public E get(intindex) {
rangeCheck(index);returnelementData(index);
}/*** 对某个索引赋值*/
public E set(intindex, E element) {
rangeCheck(index);
E oldValue=elementData(index);
elementData[index]=element;returnoldValue;
}/*** 新增一个元素,每次新增都要计算是否需要扩容*/
public booleanadd(E e) {
ensureCapacityInternal(size+ 1); //Increments modCount!!
elementData[size++] =e;return true;
}/*** 在特定的索引位置加入一个元素*/
public void add(intindex, E element) {
rangeCheckForAdd(index);//先确认是否需要对容量进行扩充,同时还需要将modCount加1
ensureCapacityInternal(size + 1); //Increments modCount!!//将索引大于等于index的元素后移一位
System.arraycopy(elementData, index, elementData, index + 1, size -index);
elementData[index]=element;
size++;
}/*** 删除特定索引的元素*/
public E remove(intindex) {
rangeCheck(index);
modCount++;
E oldValue=elementData(index);int numMoved = size - index - 1;if (numMoved > 0)//index后面的所有元素向前移动一位
System.arraycopy(elementData, index + 1, elementData, index, numMoved);//将最后一个索引为Size-1处的值设置为null,方便GC进行回收
elementData[--size] = null;returnoldValue;
}/*** 删除第一次出现的该元素,删除成功返回true*/
public booleanremove(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;
}/** 和上面的remove()方法一样,只是没有返回值和不需要做边界校验*/
private void fastRemove(intindex) {
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
}/*** 清空ArrayList,将所有元素设置为null,将size设置为0*/
public voidclear() {
modCount++;//clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i]= null;
size= 0;
}/*** 在ArrayList中一次性添加多个元素*/
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;
}/*** 在某个index处插入一个集合*/
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)//将索引大于等于index的元素向后移动
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, inttoIndex) {
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(intindex) {if (index >=size)throw newIndexOutOfBoundsException(outOfBoundsMsg(index));
}/*** 在指定索引处添加元素时判断index是否越界*/
private void rangeCheckForAdd(intindex) {if (index > size || index < 0)throw newIndexOutOfBoundsException(outOfBoundsMsg(index));
}/*** 下标越界后打印的信息*/
private String outOfBoundsMsg(intindex) {return "Index: " + index + ", Size: " +size;
}/*** 删除ArrayList中两个集合的交集元素*/
public boolean removeAll(Collection>c) {//先判断传入的集合是否为null
Objects.requireNonNull(c);//批量删除交集部分元素
return batchRemove(c, false);
}/*** 保留ArrayList中两个集合的交集元素*/
public boolean retainAll(Collection>c) {
Objects.requireNonNull(c);//批量删除非交集部分
return batchRemove(c, true);
}/***批量删除和保留两个集合的交集*/
private boolean batchRemove(Collection> c, booleancomplement) {final Object[] elementData = this.elementData;int r = 0, w = 0;boolean modified = false;try{//如果complement为true就保留两个集合的交集元素//如果complement为false就保留不在交集中的元素
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.//如果r != size 则说明在上面的操作中可能报错了,需要在finally中进行处理。直接将r及以后的数据原样保留
if (r !=size) {
System.arraycopy(elementData, r, elementData, w, size-r);
w+= size -r;
}if (w != size) {//w表示原ArrayList中能够保留下来的元素个数,保留的元素个数和原来的个数不等说明有变化,就需要修改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;
}
}returnmodified;
}/*** 将集合中的元素写入到输出流中*/
private void writeObject(java.io.ObjectOutputStream s) throwsjava.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 newConcurrentModificationException();
}
}/*** 将元素从输入流中读取到ArrayList中*/
private void readObject(java.io.ObjectInputStream s) throwsjava.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();
}
}
}/*** 返回一个下标从index开始后的list迭代器*/
public ListIterator listIterator(intindex) {if (index < 0 || index >size)throw new IndexOutOfBoundsException("Index: " +index);return newListItr(index);
}/*** 返回一个从下标0开始的list迭代器*/
public ListIteratorlistIterator() {return new ListItr(0);
}/*** 获取迭代器*/
public Iteratoriterator() {return newItr();
}/*** 私有内部类定义迭代器*/
private class Itr implements Iterator{int cursor; //游标记录了下一个元素的位置
int lastRet = -1; //index of last element returned; -1 if no such
int expectedModCount =modCount;//如果下一个元素的位置不等于size,则说明还有下一个元素
public booleanhasNext() {return cursor !=size;
}
@SuppressWarnings("unchecked")publicE next() {
checkForComodification();int i =cursor;if (i >=size)throw newNoSuchElementException();
Object[] elementData= ArrayList.this.elementData;if (i >= elementData.length)//这个集合被其他线程进行删除或者新增元素
throw newConcurrentModificationException();
cursor= i + 1;return (E) elementData[lastRet =i];
}public voidremove() {if (lastRet < 0)throw newIllegalStateException();
checkForComodification();try{
ArrayList.this.remove(lastRet);
cursor=lastRet;
lastRet= -1;
expectedModCount=modCount;
}catch(IndexOutOfBoundsException ex) {throw newConcurrentModificationException();
}
}
@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 newConcurrentModificationException();
}while (i != size && modCount ==expectedModCount) {
consumer.accept((E) elementData[i++]);
}//update once at end of iteration to reduce heap write traffic
cursor =i;
lastRet= i - 1;
checkForComodification();
}final voidcheckForComodification() {if (modCount !=expectedModCount)throw newConcurrentModificationException();
}
}/*** 私有内部类定义List迭代器,继承了上面的普通迭代器,并对功能进行了增强。list迭代器可以向前迭代*/
private class ListItr extends Itr implements ListIterator{
ListItr(intindex) {super();
cursor=index;
}//当前的游标不为0,说明前面至少还有下标为0的元素
public booleanhasPrevious() {return cursor != 0;
}public intnextIndex() {returncursor;
}public intpreviousIndex() {return cursor - 1;
}
@SuppressWarnings("unchecked")publicE previous() {
checkForComodification();int i = cursor - 1;if (i < 0)throw newNoSuchElementException();
Object[] elementData= ArrayList.this.elementData;if (i >=elementData.length)throw newConcurrentModificationException();
cursor=i;return (E) elementData[lastRet =i];
}public voidset(E e) {if (lastRet < 0)throw newIllegalStateException();
checkForComodification();try{
ArrayList.this.set(lastRet, e);
}catch(IndexOutOfBoundsException ex) {throw newConcurrentModificationException();
}
}public voidadd(E e) {
checkForComodification();try{int i =cursor;
ArrayList.this.add(i, e);
cursor= i + 1;
lastRet= -1;
expectedModCount=modCount;
}catch(IndexOutOfBoundsException ex) {throw newConcurrentModificationException();
}
}
}/*** 返回父集合的一个视图,通过fromInde,toIndex来控制视图的大小,如果fromInde == toIndex 则返回空list
* 对父和子集合的非结构性修改都会影响到对方。*/
public List subList(int fromIndex, inttoIndex) {
subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);
}/*** 对边界进行校验*/
static void subListRangeCheck(int fromIndex, int toIndex, intsize) {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 + ")");
}private class SubList extends AbstractList implementsRandomAccess {private final AbstractListparent;private final intparentOffset;private final intoffset;intsize;
SubList(AbstractList parent, int offset, int fromIndex, inttoIndex) {this.parent =parent;this.parentOffset =fromIndex;this.offset = offset +fromIndex;this.size = toIndex -fromIndex;this.modCount = ArrayList.this.modCount;
}public E set(intindex, E e) {
rangeCheck(index);
checkForComodification();
E oldValue= ArrayList.this.elementData(offset +index);
ArrayList.this.elementData[offset + index] =e;returnoldValue;
}public E get(intindex) {
rangeCheck(index);
checkForComodification();return ArrayList.this.elementData(offset +index);
}public intsize() {
checkForComodification();return this.size;
}public void add(intindex, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset+index, e);//this.modCount = parent.modCount;
this.size++;
}public E remove(intindex) {
rangeCheck(index);
checkForComodification();
E result= parent.remove(parentOffset +index);//this.modCount = parent.modCount;
this.size--;returnresult;
}protected void removeRange(int fromIndex, inttoIndex) {
checkForComodification();//parent.removeRange(parentOffset + fromIndex, parentOffset + toIndex);//this.modCount = parent.modCount;
this.size -= toIndex -fromIndex;
}public boolean addAll(Collection extends E>c) {return addAll(this.size, 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;
}public Iteratoriterator() {returnlistIterator();
}public ListIterator listIterator(final intindex) {
checkForComodification();
rangeCheckForAdd(index);final int offset = this.offset;return new ListIterator() {int cursor =index;int lastRet = -1;int expectedModCount = ArrayList.this.modCount;public booleanhasNext() {return cursor != SubList.this.size;
}
@SuppressWarnings("unchecked")publicE next() {
checkForComodification();int i =cursor;if (i >= SubList.this.size)throw newNoSuchElementException();
Object[] elementData= ArrayList.this.elementData;if (offset + i >=elementData.length)throw newConcurrentModificationException();
cursor= i + 1;return (E) elementData[offset + (lastRet =i)];
}public booleanhasPrevious() {return cursor != 0;
}
@SuppressWarnings("unchecked")publicE previous() {
checkForComodification();int i = cursor - 1;if (i < 0)throw newNoSuchElementException();
Object[] elementData= ArrayList.this.elementData;if (offset + i >=elementData.length)throw newConcurrentModificationException();
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 newConcurrentModificationException();
}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 intnextIndex() {returncursor;
}public intpreviousIndex() {return cursor - 1;
}public voidremove() {if (lastRet < 0)throw newIllegalStateException();
checkForComodification();try{
SubList.this.remove(lastRet);
cursor=lastRet;
lastRet= -1;
expectedModCount= ArrayList.this.modCount;
}catch(IndexOutOfBoundsException ex) {throw newConcurrentModificationException();
}
}public voidset(E e) {if (lastRet < 0)throw newIllegalStateException();
checkForComodification();try{
ArrayList.this.set(offset +lastRet, e);
}catch(IndexOutOfBoundsException ex) {throw newConcurrentModificationException();
}
}public voidadd(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 newConcurrentModificationException();
}
}final voidcheckForComodification() {if (expectedModCount != ArrayList.this.modCount)throw newConcurrentModificationException();
}
};
}public List subList(int fromIndex, inttoIndex) {
subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, offset, fromIndex, toIndex);
}private void rangeCheck(intindex) {if (index < 0 || index >= this.size)throw newIndexOutOfBoundsException(outOfBoundsMsg(index));
}private void rangeCheckForAdd(intindex) {if (index < 0 || index > this.size)throw newIndexOutOfBoundsException(outOfBoundsMsg(index));
}private String outOfBoundsMsg(intindex) {return "Index: " + index + ", Size: " + this.size;
}private voidcheckForComodification() {if (ArrayList.this.modCount != this.modCount)throw newConcurrentModificationException();
}public Spliteratorspliterator() {
checkForComodification();return new ArrayListSpliterator(ArrayList.this, offset, offset + this.size, this.modCount);
}
}/*** 遍历集合中的元素,并且对每个元素都进行处理
* ArrayList list = new ArrayList<>(0);
* ArrayList list2 = new ArrayList<>();
* list.add("鱼香肉丝");
* list.add("辣子鸡丁");
* System.out.println(list);
* list.forEach(s -> list2.add(s+"_"));
* System.out.println(list2);
*
* result:
* [鱼香肉丝, 辣子鸡丁]
* [鱼香肉丝_, 辣子鸡丁_]
**/@Overridepublic 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 newConcurrentModificationException();
}
}/*** 用来多线程并行迭代的迭代器,这个迭代器的主要作用就是把集合分成了好几段,每个线程执行一段,因此是线程安全的。*/@Overridepublic Spliteratorspliterator() {return new ArrayListSpliterator<>(this, 0, -1, 0);
}/**Index-based split-by-two, lazily initialized Spliterator*/
static final class ArrayListSpliterator implements Spliterator{private final ArrayListlist;private int index; //current index, modified on advance/split
private int fence; //-1 until used; then one past last index
private int expectedModCount; //initialized when fence set
/**Create new spliterator covering the given range*/ArrayListSpliterator(ArrayList list, int origin, int fence, intexpectedModCount) {this.list = list; //OK if null unless traversed
this.index =origin;this.fence =fence;this.expectedModCount =expectedModCount;
}private int getFence() { //initialize fence to size on first use
int hi; //(a specialized variant appears in method forEach)
ArrayListlst;if ((hi = fence) < 0) {if ((lst = list) == null)
hi= fence = 0;else{
expectedModCount=lst.modCount;
hi= fence =lst.size;
}
}returnhi;
}public ArrayListSpliteratortrySplit() {int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;return (lo >= mid) ? null : //divide range in half unless too small
new ArrayListSpliterator(list, lo, index =mid, expectedModCount);
}public boolean tryAdvance(Consumer super E>action) {if (action == null)throw newNullPointerException();int hi = getFence(), i =index;if (i
index= i + 1;
@SuppressWarnings("unchecked")
E e=(E) list.elementData[i];
action.accept(e);if (list.modCount !=expectedModCount)throw newConcurrentModificationException();return true;
}return false;
}public void forEachRemaining(Consumer super E>action) {int i, hi, mc; //hoist accesses and checks from loop
ArrayListlst;
Object[] a;if (action == null)throw newNullPointerException();if ((lst = list) != null && (a = lst.elementData) != null) {if ((hi = fence) < 0) {
mc=lst.modCount;
hi=lst.size;
}elsemc=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 newConcurrentModificationException();
}public longestimateSize() {return (long) (getFence() -index);
}public intcharacteristics() {return Spliterator.ORDERED | Spliterator.SIZED |Spliterator.SUBSIZED;
}
}/*** 删除符合条件的所有元素
* ArrayList list = new ArrayList<>(0);
* list.add("鱼香肉丝");
* list.add("辣子鸡丁");
* System.out.println(list);
* list.removeIf(f -> f.contains("鱼"));
* System.out.println(list);
*
* result:[鱼香肉丝, 辣子鸡丁]
* [辣子鸡丁]*/@Overridepublic 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 = newBitSet(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 newConcurrentModificationException();
}//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 newConcurrentModificationException();
}
modCount++;
}returnanyToRemove;
}/*** 将此列表的每个元素替换于运算符应用于该元素的结果,
* 也就是说将集合中的每个元素用括号里面的表达式计算一遍,然后把结果替换原来的元素
* ArrayList list = new ArrayList<>();
* list.add("1");
* list.add("2");
* System.out.println(list);
* list.replaceAll(s -> s+0);
* System.out.println(list);
* 得到的结果:[1, 2]
* [10, 20]
**/@Override
@SuppressWarnings("unchecked")public void replaceAll(UnaryOperatoroperator) {
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 newConcurrentModificationException();
}
modCount++;
}/*** 对ArrayList进行排序*/@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 newConcurrentModificationException();
}
modCount++;
}
}