ArrayList是我们开发中最常用的集合,但是很多人不知道它的源码,所以在面试的时候,面试官问到是不可能的回答一个有点深入的问题。今天我们就一起来探究ArrayList的源码。1.简介ArrayList底层是一个数组,它允许有null元素,并且可以动态扩展。size、isEmpty、get、set、add等方法时间复杂度为O(1)非线程安全,并发修改时会抛出ConcurrentModificationException。2.初始化//初始容量privatestaticfinalintDEFAULT_CAPACITY=10;//空数组privatestaticfinalObject[]EMPTY_ELEMENTDATA={};//默认空数组privatestaticfinalObject[]DEFAULTCAPACITY_EMPTY_ELEMENTDATA={};//arraytransient用于存储元素Object[]elementData;//无参数初始化,默认为空数组>0){this.elementData=newObject[initialCapacity];}elseif(initialCapacity==0){this.elementData=EMPTY_ELEMENTDATA;}else{thrownewIllegalArgumentException("非法容量:"+initialCapacity);}}记住:没有参数初始化的时候,默认是一个空数组,没有初始化容量的大小。首次添加元素时会初始化容量。3.添加元素publicbooleanadd(Ee){//保证数组容量足够,size为元素个数ensureCapacityInternal(size+1);//直接赋值elementData[size++]=e;returntrue;}//确保数组容量足够){//如果数组等于空数组,则最小容量为10if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA){returnMath.max(DEFAULT_CAPACITY,minCapacity);}returnminCapacity;}privatevoidensureExplicitCapacity(intminCapacity){modCount++;//如果需要的最小容量大于数组长度,就展开if(minCapacity-elementData.length>0)grow(minCapacity);}看看展开逻辑://要展开,复制旧的数据到新数组privatevoidgrow(intminCapacity){intoldCapacity=elementData.长度;//oldCapacity>>1是oldCapacity除以2,也就是1.5倍的扩展intnewCapacity=oldCapacity+(oldCapacity>>1);//如果扩展容量小于最小容量,则扩展容量等于最小容量if(newCapacity-minCapacity<0)newCapacity=minCapacity;//如果扩展容量大于Integer的最大值,则使用Integer的最大值if(newCapacity-MAX_ARRAY_SIZE>0)newCapacity=hugeCapacity(minCapacity);//扩容赋值给原数组elementData=Arrays.copyOf(elementData,newCapacity);}可以看到扩容是原来容量的1.5倍,不是翻倍。最大容量是Integer的最大值。添加元素时,没有元素验证,可以为null再看数组复制的逻辑,这里是Arrays类中的方法:/***@paramoriginal原始数组*@paramnewLength新容量大小*/publicstatic
