本节介绍使用最简单的代码创建ArrayList,添加11个元素以及底层源代码。 说之前,请向大家普及一点知识:
”ArrayList的基础是通过数组实现的
”数组创建时,大小固定,超过数组大小时创建新数组
"接下来,阵列扩展实质上是新制作更大尺寸的新阵列
@Test
公共语音测试阵列列表(
制作统称为String的ArrayList ()这里什么是总称不重要吗() ) ) )。
ArrayList list=new ArrayList (;
//按顺序添加11个元素
list.add('1);
list.add(2);
list.add(3);
list.add(4);
list.add('5);
list.add('6);
list.add('7);
list.add('8);
list.add('9);
list.add('10 );
list.add('11 );
}
在上面的代码中,我们只调用了add (。 add ) )的源代码之前,必须介绍ArrayList中的常量和变量。 下面的源代码中涉及到这些,所以我怕你们到时候会皱起眉头
私密性staticfinalintdefault _ capacity=10;
privatestaticfinalobject [ ] default capacity _ empty _ element data={ };
传输对象[ ] element data;
私密int size;
privatestaticfinalintmax _ array _ size=integer.max _ value-8;
”default _ capacity:default _ capcity,缺省容量大小,即在勤奋创建数组并将第一个元素添加到其中时数组的缺省容量大小
”default capacity _ empty _ elementdata:default capacity _ empty _ element data是缺省的空数组,表示element data为{}或空数组
" elementData :显示当前存储元素的数组
”size :他现在显示在添加新元素之前数组中有效元素的数量。 例如,如果数组的长度为10,并且只存储了五个元素,则有效长度为5
" MAX_ARRAY_SIZE :标识当前数组中可保存元素最大长度的最大数组长度。 值为integer _ max _ value-8,2147483647-8,其中8字节表示用于存储数组本身的内存大小。
现在,add ) )里面,看看他们具体是怎么实现的。 下面的代码。
publicbooleanadd{
企业空间国际(size 1;//增量模式计数!
元素数据[ size ]=e;
返回真;
}
”ensurecapacityinternal(size1) :意思是“确保内部变量”,是什么意思? 他用于确定当前数组的容量是否足够,不足时扩展容量。 稍后进入这个方法,看看他是如何具体实现的。 size表示当前未添加新元素的前一个数组的有效元素数,size 1表示传递给当前数组的最小容量(有效长度)
”elementData[size ]=e :此语句表示对数组执行赋值操作,简单来说就是向数组中添加元素。 例如,如果当前数组中已经存在三个元素,则接下来添加另一个元素a,该步骤为元素数据[3]=a;
”返回真:表示添加成功;
然后,转至ensureCapacityInternal (),如以下代码所示:
私有语音容量国际(int min capacity ) {
ensureexplicitcapacity (计算容量(element data,minCapacity ) );
}
它包括两种方法: ensureExplicitCapacity ()和calculateCapacity () )。
”calculateCapacity () :用于计算当前数组所需的最小容量minCapacity的计算容量。 请理解为当前数组的有效长度。 源代码如下:
私有数据计算能力(object [ ] element data,in
t minCapacity) { //若传入的是个空数组,则返回的是最小容量 是 默认容量(10) 和 当前最小容量(0)之间的最大值if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
PS:第一次添加元素时calculateCapacity返回的最小容量minCapacity是10,从第二次开始minCapacity为2,第三次为3,依次类推..在这里第一次返回10大家不要纠结它的意义,重点在第二次及之后表示的意思
》ensureExplicitCapacity():判断是否需要扩容;查看它的源码:
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code当最小容量大于当前的数组大小时
if (minCapacity - elementData.length > 0) //计算扩容后的数组大小
grow(minCapacity);
}
我们第一次list.add(),最小容量minCapacity是10,elementData.length长度为0,所以条件成立,进入grow()(第二次minCapacity是2,elementData.length为10,条件不成立就不再扩容了;当第11次时,11>10,又可以扩容了)
private void grow(int minCapacity) {
// 得到当前数组的大小,即老数组大小
int oldCapacity = elementData.length;
//将旧数组大小+旧数组/2,即旧数组的1.5倍是新数组的大小(先不要在意>>1的意思,你只要知道oldCapacity >> 1表示oldCapacity/2就行)
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果扩容后的是数组大小还是小于最小所需容量,直接让minCapacity赋值到新容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//若新容量大小大于数组长度的最大预设值;由于扩容后是原数组的1.5倍,则非常有可能会溢出这个预设值
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);
}
相信大家这上面大部分都能够理解,可能就一个地方不太清楚:当newCapacity > MAX_ARRAY_SIZE(新容量大于预设值较特殊的情况,一般数组长度不会扩容到这么大)时调用hugeCapacity有啥用?我们看下hugeCapacity()的源码:
private static int hugeCapacity(int minCapacity) {
//若最小容量小于0的情况,抛出异常
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//若最小容量>最大预设值,返回Integer.Max_VALUE,否则是MAX_ARRAY_SIZE(Integer.Max_VALUE-8)
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
hugeCapacity()是用来限制新容量的大小的,是不能超出Integer.MAX_VALUE值的,最后说一点,数组的最大长度并不是MAX_ARRAY_SIZE,而是Integer.MAX_VALUE。
》Arrays.copyOf(elementData, newCapacity),就不看源码了,简单说一下:它这个方法能返回一个扩容后的数组,将旧数组elementData的数据复制到长度为newCapacity的新数组中。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持站圈网。