Java编程中ArrayList源码分析
之前看过一句话,说的特别好。有人问阅读源码有什么用?学习别人实现某个功能的设计思路,提高自己的编程水平。
是的,大家都实现一个功能,不同的人有不同的设计思路,有的人用一万行代码,有的人用五千行。有的人代码运行需要的几十秒,有的人只需要的几秒。。下面进入正题了。
本文的主要内容:
· 详细注释了ArrayList的实现,基于JDK1.8。
·迭代器SubList部分未详细解释,会放到其他源码解读里面。此处重点关注ArrayList本身实现。
·没有采用标准的注释,并适当调整了代码的缩进以方便介绍
importjava.util.AbstractList; importjava.util.Arrays; importjava.util.BitSet; importjava.util.Collection; importjava.util.Comparator; importjava.util.ConcurrentModificationException; importjava.util.Iterator; importjava.util.List; importjava.util.ListIterator; importjava.util.NoSuchElementException; importjava.util.Objects; importjava.util.RandomAccess; importjava.util.Spliterator; importjava.util.function.Consumer; importjava.util.function.Predicate; importjava.util.function.UnaryOperator; /** *概述: *List接口可调整大小的数组实现。实现所有可选的List操作,并允许所有元素,包括null,元素可重复。 *除了列表接口外,该类提供了一种方法来操作该数组的大小来存储该列表中的数组的大小。 * *时间复杂度: *方法size、isEmpty、get、set、iterator和listIterator的调用是常数时间的。 *添加删除的时间复杂度为O(N)。其他所有操作也都是线性时间复杂度。 * *容量: *每个ArrayList都有容量,容量大小至少为List元素的长度,默认初始化为10。 *容量可以自动增长。 *如果提前知道数组元素较多,可以在添加元素前通过调用ensureCapacity()方法提前增加容量以减小后期容量自动增长的开销。 *也可以通过带初始容量的构造器初始化这个容量。 * *线程不安全: *ArrayList不是线程安全的。 *如果需要应用到多线程中,需要在外部做同步 * *modCount: *定义在AbstractList中:protectedtransientintmodCount=0; *已从结构上修改此列表的次数。从结构上修改是指更改列表的大小,或者打乱列表,从而使正在进行的迭代产生错误的结果。 *此字段由iterator和listiterator方法返回的迭代器和列表迭代器实现使用。 *如果意外更改了此字段中的值,则迭代器(或列表迭代器)将抛出concurrentmodificationexception来响应next、remove、previous、set或add操作。 *在迭代期间面临并发修改时,它提供了快速失败行为,而不是非确定性行为。 *子类是否使用此字段是可选的。 *如果子类希望提供快速失败迭代器(和列表迭代器),则它只需在其add(int,e)和remove(int)方法(以及它所重写的、导致列表结构上修改的任何其他方法)中增加此字段。 *对add(int,e)或remove(int)的单个调用向此字段添加的数量不得超过1,否则迭代器(和列表迭代器)将抛出虚假的concurrentmodificationexceptions。 *如果某个实现不希望提供快速失败迭代器,则可以忽略此字段。 * *transient: *默认情况下,对象的所有成员变量都将被持久化.在某些情况下,如果你想避免持久化对象的一些成员变量,你可以使用transient关键字来标记他们,transient也是java中的保留字(JDK1.8) */ publicclassArrayListextendsAbstractList implementsList ,RandomAccess,Cloneable,java.io.Serializable { privatestaticfinallongserialVersionUID=8683452581122892189L; //默认初始容量 privatestaticfinalintDEFAULT_CAPACITY=10; //用于空实例共享空数组实例。 privatestaticfinalObject[]EMPTY_ELEMENTDATA={}; //默认的空数组 privatestaticfinalObject[]DEFAULTCAPACITY_EMPTY_ELEMENTDATA={}; //对的,存放元素的数组,包访问权限 transientObject[]elementData; //大小,创建对象时Java会将int初始化为0 privateintsize; //用指定的数设置初始化容量的构造函数,负数会抛出异常 publicArrayList(intinitialCapacity){ if(initialCapacity>0){ this.elementData=newObject[initialCapacity]; }elseif(initialCapacity==0){ this.elementData=EMPTY_ELEMENTDATA; }else{ thrownewIllegalArgumentException("IllegalCapacity:"+initialCapacity); } } //默认构造函数,使用控数组初始化 publicArrayList(){ this.elementData=DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //以集合的迭代器返回顺序,构造一个含有集合中元素的列表 publicArrayList(Collectionc){ elementData=c.toArray(); if((size=elementData.length)!=0){ //c.toarray可能(错误地)不返回对象[](见JAVABUG编号6260652) if(elementData.getClass()!=Object[].class) elementData=Arrays.copyOf(elementData,size,Object[].class); }else{ //使用空数组 this.elementData=EMPTY_ELEMENTDATA; } } //因为容量常常会大于实际元素的数量。内存紧张时,可以调用该方法删除预留的位置,调整容量为元素实际数量。 //如果确定不会再有元素添加进来时也可以调用该方法来节约空间 publicvoidtrimToSize(){ modCount++; if(size minExpand){ ensureExplicitCapacity(minCapacity); } } //用于添加元素时,确保数组容量 privatevoidensureCapacityInternal(intminCapacity){ //使用默认值和参数中较大者作为容量预设值 if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA){ minCapacity=Math.max(DEFAULT_CAPACITY,minCapacity); } ensureExplicitCapacity(minCapacity); } //如果参数大于数组容量,就增加数组容量 privatevoidensureExplicitCapacity(intminCapacity){ modCount++; if(minCapacity-elementData.length>0) grow(minCapacity); } //数组的最大容量,可能会导致内存溢出(VM内存限制) privatestaticfinalintMAX_ARRAY_SIZE=Integer.MAX_VALUE-8; //增加容量,以确保它可以至少持有由参数指定的元素的数目 privatevoidgrow(intminCapacity){ intoldCapacity=elementData.length; //预设容量增加一半 intnewCapacity=oldCapacity+(oldCapacity>>1); //取与参数中的较大值 if(newCapacity-minCapacity<0)//即newCapacity 0) newCapacity=hugeCapacity(minCapacity); elementData=Arrays.copyOf(elementData,newCapacity); } //检查是否溢出,若没有溢出,返回最大整数值(java中的int为4字节,所以最大为0x7fffffff)或默认最大值 privatestaticinthugeCapacity(intminCapacity){ if(minCapacity<0)//溢出 thrownewOutOfMemoryError(); return(minCapacity>MAX_ARRAY_SIZE)?Integer.MAX_VALUE:MAX_ARRAY_SIZE; } //返回数组大小 publicintsize(){ returnsize; } //是否为空 publicbooleanisEmpty(){ returnsize==0; } //是否包含一个数返回bool publicbooleancontains(Objecto){ returnindexOf(o)>=0; } //返回一个值在数组首次出现的位置,会根据是否为null使用不同方式判断。不存在就返回-1。时间复杂度为O(N) publicintindexOf(Objecto){ if(o==null){ for(inti=0;i =0;i--) if(elementData[i]==null) returni; }else{ for(inti=size-1;i>=0;i--) if(o.equals(elementData[i])) returni; } return-1; } //返回副本,元素本身没有被复制,复制过程数组发生改变会抛出异常 publicObjectclone(){ try{ ArrayList>v=(ArrayList>)super.clone(); v.elementData=Arrays.copyOf(elementData,size); v.modCount=0; returnv; }catch(CloneNotSupportedExceptione){ thrownewInternalError(e); } } //转换为Object数组,使用Arrays.copyOf()方法 publicObject[]toArray(){ returnArrays.copyOf(elementData,size); } //返回一个数组,使用运行时确定类型,该数组包含在这个列表中的所有元素(从第一到最后一个元素) //返回的数组容量由参数和本数组中较大值确定 @SuppressWarnings("unchecked") public T[]toArray(T[]a){ if(a.length size) a[size]=null; returna; } //返回指定位置的值,因为是数组,所以速度特别快 @SuppressWarnings("unchecked") EelementData(intindex){ return(E)elementData[index]; } //返回指定位置的值,但是会检查这个位置数否超出数组长度 publicEget(intindex){ rangeCheck(index); returnelementData(index); } //设置指定位置为一个新值,并返回之前的值,会检查这个位置是否超出数组长度 publicEset(intindex,Eelement){ rangeCheck(index); EoldValue=elementData(index); elementData[index]=element; returnoldValue; } //添加一个值,首先会确保容量 publicbooleanadd(Ee){ ensureCapacityInternal(size+1); elementData[size++]=e; returntrue; } //指定位置添加一个值,会检查添加的位置和容量 publicvoidadd(intindex,Eelement){ rangeCheckForAdd(index); ensureCapacityInternal(size+1); //publicstaticvoidarraycopy(Objectsrc,intsrcPos,Objectdest,intdestPos,intlength) //src:源数组;srcPos:源数组要复制的起始位置;dest:目的数组;destPos:目的数组放置的起始位置;length:复制的长度 System.arraycopy(elementData,index,elementData,index+1,size-index); elementData[index]=element; size++; } //删除指定位置的值,会检查添加的位置,返回之前的值 publicEremove(intindex){ rangeCheck(index); modCount++; EoldValue=elementData(index); intnumMoved=size-index-1; if(numMoved>0)System.arraycopy(elementData,index+1,elementData,index,numMoved); elementData[--size]=null;//便于垃圾回收期回收 returnoldValue; } //删除指定元素首次出现的位置 publicbooleanremove(Objecto){ if(o==null){ for(intindex=0;index 0) System.arraycopy(elementData,index+1,elementData,index,numMoved); elementData[--size]=null;//cleartoletGCdoitswork } //清空数组,把每一个值设为null,方便垃圾回收(不同于reset,数组默认大小有改变的话不会重置) publicvoidclear(){ modCount++; for(inti=0;i c){ Object[]a=c.toArray(); intnumNew=a.length; ensureCapacityInternal(size+numNew); System.arraycopy(a,0,elementData,size,numNew); size+=numNew; returnnumNew!=0; } //功能同上,从指定位置开始添加 publicbooleanaddAll(intindex,Collectionc){ rangeCheckForAdd(index); Object[]a=c.toArray();//要添加的数组 intnumNew=a.length;//要添加的数组长度 ensureCapacityInternal(size+numNew);//确保容量 intnumMoved=size-index;//不会移动的长度(前段部分) if(numMoved>0)//有不需要移动的,就通过自身复制,把数组后部分需要移动的移动到正确位置 System.arraycopy(elementData,index,elementData,index+numNew,numMoved); System.arraycopy(a,0,elementData,index,numNew);//新的数组添加到改变后的原数组中间 size+=numNew; returnnumNew!=0; } //删除指定范围元素。参数为开始删的位置和结束位置 protectedvoidremoveRange(intfromIndex,inttoIndex){ modCount++; intnumMoved=size-toIndex;//后段保留的长度 System.arraycopy(elementData,toIndex,elementData,fromIndex,numMoved); intnewSize=size-(toIndex-fromIndex); for(inti=newSize;i =size) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); } //检查是否溢出 privatevoidrangeCheckForAdd(intindex){ if(index>size||index<0) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); } //抛出的异常的详情 privateStringoutOfBoundsMsg(intindex){ return"Index:"+index+",Size:"+size; } //删除指定集合的元素 publicbooleanremoveAll(Collection>c){ Objects.requireNonNull(c);//检查参数是否为null returnbatchRemove(c,false); } //仅保留指定集合的元素 publicbooleanretainAll(Collection>c){ Objects.requireNonNull(c); returnbatchRemove(c,true); } /** *源码解读BYhttp://anxpp.com/ *@paramcomplementtrue时从数组保留指定集合中元素的值,为false时从数组删除指定集合中元素的值。 *@return数组中重复的元素都会被删除(而不是仅删除一次或几次),有任何删除操作都会返回true */ privatebooleanbatchRemove(Collection>c,booleancomplement){ finalObject[]elementData=this.elementData; intr=0,w=0; booleanmodified=false; try{ //遍历数组,并检查这个集合是否包含对应的值,移动要保留的值到数组前面,w最后值为要保留的元素的数量 //简单点:若保留,就将相同元素移动到前段;若删除,就将不同元素移动到前段 for(;r 0){ ensureCapacityInternal(size); Object[]a=elementData; //读入所有元素 for(inti=0;i listIterator(intindex){ if(index<0||index>size) thrownewIndexOutOfBoundsException("Index:"+index); returnnewListItr(index); } //返回ListIterator,开始位置为0 publicListIterator listIterator(){ returnnewListItr(0); } //返回普通迭代器 publicIterator iterator(){ returnnewItr(); } //通用的迭代器实现 privateclassItrimplementsIterator { intcursor;//游标,下一个元素的索引,默认初始化为0 intlastRet=-1;//上次访问的元素的位置 intexpectedModCount=modCount;//迭代过程不运行修改数组,否则就抛出异常 //是否还有下一个 publicbooleanhasNext(){ returncursor!=size; } //下一个元素 @SuppressWarnings("unchecked") publicEnext(){ checkForComodification();//检查数组是否被修改 inti=cursor; if(i>=size) thrownewNoSuchElementException(); Object[]elementData=ArrayList.this.elementData; if(i>=elementData.length) thrownewConcurrentModificationException(); cursor=i+1;//向后移动游标 return(E)elementData[lastRet=i];//设置访问的位置并返回这个值 } //删除元素 publicvoidremove(){ if(lastRet<0) thrownewIllegalStateException(); checkForComodification();//检查数组是否被修改 try{ ArrayList.this.remove(lastRet); cursor=lastRet; lastRet=-1; expectedModCount=modCount; }catch(IndexOutOfBoundsExceptionex){ thrownewConcurrentModificationException(); } } @Override @SuppressWarnings("unchecked") publicvoidforEachRemaining(Consumerconsumer){ Objects.requireNonNull(consumer); finalintsize=ArrayList.this.size; inti=cursor; if(i>=size){ return; } finalObject[]elementData=ArrayList.this.elementData; if(i>=elementData.length){ thrownewConcurrentModificationException(); } while(i!=size&&modCount==expectedModCount){ consumer.accept((E)elementData[i++]); } cursor=i; lastRet=i-1; checkForComodification(); } //检查数组是否被修改 finalvoidcheckForComodification(){ if(modCount!=expectedModCount) thrownewConcurrentModificationException(); } } //ListIterator迭代器实现 privateclassListItrextendsItrimplementsListIterator { ListItr(intindex){ super(); cursor=index; } publicbooleanhasPrevious(){ returncursor!=0; } publicintnextIndex(){ returncursor; } publicintpreviousIndex(){ returncursor-1; } @SuppressWarnings("unchecked") publicEprevious(){ checkForComodification(); inti=cursor-1; if(i<0) thrownewNoSuchElementException(); Object[]elementData=ArrayList.this.elementData; if(i>=elementData.length) thrownewConcurrentModificationException(); cursor=i; return(E)elementData[lastRet=i]; } publicvoidset(Ee){ if(lastRet<0) thrownewIllegalStateException(); checkForComodification(); try{ ArrayList.this.set(lastRet,e); }catch(IndexOutOfBoundsExceptionex){ thrownewConcurrentModificationException(); } } publicvoidadd(Ee){ checkForComodification(); try{ inti=cursor; ArrayList.this.add(i,e); cursor=i+1; lastRet=-1; expectedModCount=modCount; }catch(IndexOutOfBoundsExceptionex){ thrownewConcurrentModificationException(); } } } //返回指定范围的子数组 publicList subList(intfromIndex,inttoIndex){ subListRangeCheck(fromIndex,toIndex,size); returnnewSubList(this,0,fromIndex,toIndex); } //安全检查 staticvoidsubListRangeCheck(intfromIndex,inttoIndex,intsize){ if(fromIndex<0) thrownewIndexOutOfBoundsException("fromIndex="+fromIndex); if(toIndex>size) thrownewIndexOutOfBoundsException("toIndex="+toIndex); if(fromIndex>toIndex) thrownewIllegalArgumentException("fromIndex("+fromIndex+ ")>toIndex("+toIndex+")"); } //子数组 privateclassSubListextendsAbstractList implementsRandomAccess{ privatefinalAbstractList parent; privatefinalintparentOffset; privatefinalintoffset; intsize; SubList(AbstractList parent,intoffset,intfromIndex,inttoIndex){ this.parent=parent; this.parentOffset=fromIndex; this.offset=offset+fromIndex; this.size=toIndex-fromIndex; this.modCount=ArrayList.this.modCount; } publicEset(intindex,Ee){ rangeCheck(index); checkForComodification(); EoldValue=ArrayList.this.elementData(offset+index); ArrayList.this.elementData[offset+index]=e; returnoldValue; } publicEget(intindex){ rangeCheck(index); checkForComodification(); returnArrayList.this.elementData(offset+index); } publicintsize(){ checkForComodification(); returnthis.size; } publicvoidadd(intindex,Ee){ rangeCheckForAdd(index); checkForComodification(); parent.add(parentOffset+index,e); this.modCount=parent.modCount; this.size++; } publicEremove(intindex){ rangeCheck(index); checkForComodification(); Eresult=parent.remove(parentOffset+index); this.modCount=parent.modCount; this.size--; returnresult; } protectedvoidremoveRange(intfromIndex,inttoIndex){ checkForComodification(); parent.removeRange(parentOffset+fromIndex,parentOffset+toIndex); this.modCount=parent.modCount; this.size-=toIndex-fromIndex; } publicbooleanaddAll(Collectionc){ returnaddAll(this.size,c); } publicbooleanaddAll(intindex,Collectionc){ rangeCheckForAdd(index); intcSize=c.size(); if(cSize==0) returnfalse; checkForComodification(); parent.addAll(parentOffset+index,c); this.modCount=parent.modCount; this.size+=cSize; returntrue; } publicIterator iterator(){ returnlistIterator(); } publicListIterator listIterator(finalintindex){ checkForComodification(); rangeCheckForAdd(index); finalintoffset=this.offset; returnnewListIterator (){ intcursor=index; intlastRet=-1; intexpectedModCount=ArrayList.this.modCount; publicbooleanhasNext(){ returncursor!=SubList.this.size; } @SuppressWarnings("unchecked") publicEnext(){ checkForComodification(); inti=cursor; if(i>=SubList.this.size) thrownewNoSuchElementException(); Object[]elementData=ArrayList.this.elementData; if(offset+i>=elementData.length) thrownewConcurrentModificationException(); cursor=i+1; return(E)elementData[offset+(lastRet=i)]; } publicbooleanhasPrevious(){ returncursor!=0; } @SuppressWarnings("unchecked") publicEprevious(){ checkForComodification(); inti=cursor-1; if(i<0) thrownewNoSuchElementException(); Object[]elementData=ArrayList.this.elementData; if(offset+i>=elementData.length) thrownewConcurrentModificationException(); cursor=i; return(E)elementData[offset+(lastRet=i)]; } @SuppressWarnings("unchecked") publicvoidforEachRemaining(Consumerconsumer){ Objects.requireNonNull(consumer); finalintsize=SubList.this.size; inti=cursor; if(i>=size){ return; } finalObject[]elementData=ArrayList.this.elementData; if(offset+i>=elementData.length){ thrownewConcurrentModificationException(); } while(i!=size&&modCount==expectedModCount){ consumer.accept((E)elementData[offset+(i++)]); } //updateonceatendofiterationtoreduceheapwritetraffic lastRet=cursor=i; checkForComodification(); } publicintnextIndex(){ returncursor; } publicintpreviousIndex(){ returncursor-1; } publicvoidremove(){ if(lastRet<0) thrownewIllegalStateException(); checkForComodification(); try{ SubList.this.remove(lastRet); cursor=lastRet; lastRet=-1; expectedModCount=ArrayList.this.modCount; }catch(IndexOutOfBoundsExceptionex){ thrownewConcurrentModificationException(); } } publicvoidset(Ee){ if(lastRet<0) thrownewIllegalStateException(); checkForComodification(); try{ ArrayList.this.set(offset+lastRet,e); }catch(IndexOutOfBoundsExceptionex){ thrownewConcurrentModificationException(); } } publicvoidadd(Ee){ checkForComodification(); try{ inti=cursor; SubList.this.add(i,e); cursor=i+1; lastRet=-1; expectedModCount=ArrayList.this.modCount; }catch(IndexOutOfBoundsExceptionex){ thrownewConcurrentModificationException(); } } finalvoidcheckForComodification(){ if(expectedModCount!=ArrayList.this.modCount) thrownewConcurrentModificationException(); } }; } publicList subList(intfromIndex,inttoIndex){ subListRangeCheck(fromIndex,toIndex,size); returnnewSubList(this,offset,fromIndex,toIndex); } privatevoidrangeCheck(intindex){ if(index<0||index>=this.size) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); } privatevoidrangeCheckForAdd(intindex){ if(index<0||index>this.size) thrownewIndexOutOfBoundsException(outOfBoundsMsg(index)); } privateStringoutOfBoundsMsg(intindex){ return"Index:"+index+",Size:"+this.size; } privatevoidcheckForComodification(){ if(ArrayList.this.modCount!=this.modCount) thrownewConcurrentModificationException(); } publicSpliterator spliterator(){ checkForComodification(); returnnewArrayListSpliterator (ArrayList.this,offset,offset+this.size,this.modCount); } } @Override publicvoidforEach(Consumeraction){ Objects.requireNonNull(action); finalintexpectedModCount=modCount; @SuppressWarnings("unchecked") finalE[]elementData=(E[])this.elementData; finalintsize=this.size; for(inti=0;modCount==expectedModCount&&i late-binding *andfail-fast{@linkSpliterator}overtheelementsinthis *list. * * The{@codeSpliterator}reports{@linkSpliterator#SIZED}, *{@linkSpliterator#SUBSIZED},and{@linkSpliterator#ORDERED}. *Overridingimplementationsshoulddocumentthereportingofadditional *characteristicvalues. * *@returna{@codeSpliterator}overtheelementsinthislist *@since1.8 */ @Override publicSpliterator
spliterator(){ returnnewArrayListSpliterator<>(this,0,-1,0); } /**Index-basedsplit-by-two,lazilyinitializedSpliterator*/ staticfinalclassArrayListSpliterator implementsSpliterator { /* *IfArrayListswereimmutable,orstructurallyimmutable(no *adds,removes,etc),wecouldimplementtheirspliterators *withArrays.spliterator.Insteadwedetectasmuch *interferenceduringtraversalaspracticalwithout *sacrificingmuchperformance.Werelyprimarilyon *modCounts.Thesearenotguaranteedtodetectconcurrency *violations,andaresometimesoverlyconservativeabout *within-threadinterference,butdetectenoughproblemsto *beworthwhileinpractice.Tocarrythisout,we(1)lazily *initializefenceandexpectedModCountuntilthelatest *pointthatweneedtocommittothestatewearechecking *against;thusimprovingprecision.(Thisdoesn'tapplyto *SubLists,thatcreatespliteratorswithcurrentnon-lazy *values).(2)Weperformonlyasingle *ConcurrentModificationExceptioncheckattheendofforEach *(themostperformance-sensitivemethod).WhenusingforEach *(asopposedtoiterators),wecannormallyonlydetect *interferenceafteractions,notbefore.Further *CME-triggeringchecksapplytoallotherpossible *violationsofassumptionsforexamplenullortoo-small *elementDataarraygivenitssize(),thatcouldonlyhave *occurredduetointerference.Thisallowstheinnerloop *offorEachtorunwithoutanyfurtherchecks,and *simplifieslambda-resolution.Whilethisdoesentaila *numberofchecks,notethatinthecommoncaseof *list.stream().forEach(a),nochecksorothercomputation *occuranywhereotherthaninsideforEachitself.Theother *less-often-usedmethodscannottakeadvantageofmostof *thesestreamlinings. */ privatefinalArrayList list; privateintindex;//currentindex,modifiedonadvance/split privateintfence;//-1untilused;thenonepastlastindex privateintexpectedModCount;//initializedwhenfenceset /**Createnewspliteratorcoveringthegivenrange*/ ArrayListSpliterator(ArrayList list,intorigin,intfence, intexpectedModCount){ this.list=list;//OKifnullunlesstraversed this.index=origin; this.fence=fence; this.expectedModCount=expectedModCount; } privateintgetFence(){//initializefencetosizeonfirstuse inthi;//(aspecializedvariantappearsinmethodforEach) ArrayList lst; if((hi=fence)<0){ if((lst=list)==null) hi=fence=0; else{ expectedModCount=lst.modCount; hi=fence=lst.size; } } returnhi; } publicArrayListSpliterator trySplit(){ inthi=getFence(),lo=index,mid=(lo+hi)>>>1; return(lo>=mid)?null://dividerangeinhalfunlesstoosmall newArrayListSpliterator (list,lo,index=mid, expectedModCount); } publicbooleantryAdvance(Consumeraction){ if(action==null) thrownewNullPointerException(); inthi=getFence(),i=index; if(i action){ inti,hi,mc;//hoistaccessesandchecksfromloop ArrayListlst;Object[]a; if(action==null) thrownewNullPointerException(); if((lst=list)!=null&&(a=lst.elementData)!=null){ if((hi=fence)<0){ mc=lst.modCount; hi=lst.size; } else mc=expectedModCount; if((i=index)>=0&&(index=hi)<=a.length){ for(;i filter){ Objects.requireNonNull(filter); //figureoutwhichelementsaretoberemoved //anyexceptionthrownfromthefilterpredicateatthisstage //willleavethecollectionunmodified intremoveCount=0; finalBitSetremoveSet=newBitSet(size); finalintexpectedModCount=modCount; finalintsize=this.size; for(inti=0;modCount==expectedModCount&&i0; if(anyToRemove){ finalintnewSize=size-removeCount; for(inti=0,j=0;(i operator){ Objects.requireNonNull(operator); finalintexpectedModCount=modCount; finalintsize=this.size; for(inti=0;modCount==expectedModCount&&i c){ finalintexpectedModCount=modCount; Arrays.sort((E[])elementData,0,size,c); if(modCount!=expectedModCount){ thrownewConcurrentModificationException(); } modCount++; } }
总结
以上就是本文关于Java编程中ArrayList源码分析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!