我想大家都相当熟悉ArrayList,今天我们将破译ArrayList的源代码,向大家解释ArrayList扩展的基本原理。
每个人都用过,让我简单介绍一下。 ArrayList实现了List的接口,实现了序列化。 同样,具有collection的方法、add、remove等的时间复杂性都是o(1),n个数据的o(1 )。 现在,让我们具体看看ArrayList的源代码。 笔者使用的是JDK 1.8版。
//*
* thearraybufferintowhichtheelementsofthearraylistarestored。
* thecapacityofthearraylististhelengthofthisarraybuffer.any
* emptyarraylistwithelementdata==default capacity _ empty _ element data
* willbeexpandedtodefault _ capacitywhenthefirstelementisadded。
*/
传输对象[ ] element data; //non-privatetosimplifynestedclassaccess
//*
* constructsanemptylistwithaninitialcapacityoften。
*/
公共阵列() {
this.element数据=default capacity _ empty _ element data;
}
现在,您可以看到我们的数据实际上位于ArrayList引用的Object数组中,即元素数据数组中。 让我们看看那个add方法:
//*
* appendsthespecifiedelementtotheendofthislist。
*
* @ parameelementtobeappendedtothislist
*@returntrue(asspecifiedby ) @linkcollection#add ) )
*/
publicbooleanadd{
企业空间国际(size 1;//增量模式计数!
元素数据[ size ]=e;
返回真;
}
私有语音容量国际(int min capacity ) {
if (元素数据==default capacity _ empty _ element data ) {
mincapacity=math.max (default _ capacity,mincapacity;
}
企业应用管理(mincapacity;
}
隐私保护功能(in min capacity ) {
模具计数;
//overflow-conscious代码
if (最大容量元素数据.长度0 ) ) )。
微容量;
}
从add引入的元素中,必须通过ensure方法判断大小,首先确定要获得最小容量,然后将最小容量与当前数据所需的容量进行最大匹配,如果未满足最小容量,则必须增加大小。
//*
* increasesthecapacitytoensurethatitcanholdatleastthe
* numberofelementsspecifiedbytheminimumcapacityargument。
*
* @ parammincapacitythedesiredminimumcapacity
*/
隐私保护(int min capacity ) {
//overflow-conscious代码
intoldcapacity=element data.length;
intnewcapacity=old capacity (old capacity 1;
新容量-最小容量(if ) )。
newCapacity=minCapacity;
if(newcapacity-max_Array_size0) )。
新容量=huge capacity (mincapacity;
//mincapacityisusuallyclosetosize,so this is a win:
元素数据=arrays.copy of (element data,newCapacity );
}
其中,新容量是对旧的向后移动1位,即以二进制数向右移动的容量进行判断,新的小于最小容量时分配为最小容量,超过最大值时分配为int的最大值,即2^31-1,以16进制数0 x7 fffffffffff
在这里可以制作测试demo。 由于属性是非公有的,所以使用反射的方法获取(有关使用反射的信息,请参考笔者的其他文章)。
publicstaticvoidmain (字符串[ ] args ) {
ArrayListlist=new ArrayList (;
testintvaluevalue=new test intvalue (;
list.add(ss );
intactuallength=value.getactuallength (列表;
int size=list.size (;
system.out.println('list此时的容量为' actualLength );
system.out.println('list此时的大小为' size );
}
//*
*反射获取元件数据容量大小
* @param mList
* @return
*/
publicintgetactuallength (阵列列表列表) {
Class mClass=mList.getClass (;
Field f=null;
int length=0;
try {
f=m class.getdeclaredfield (元素数据);
f .设置可访问(true );
object[]o=(object[] ) f.get ) mlist;
length=o.length;
}catch(exceptione ) {
e .打印堆栈跟踪(;
}
返回长度;
}
此时,由于只增加了一个值,因此此时的大小为1,容量大小为10 :
如果我们给他填10以上的值:
此时,容量的大小已经达到15。 大小确实来自十五,所以他的扩展容量大约大了1.5倍。
以上就是扩大的过程。 谢谢你~