所在的位置: java >> 学习资料 >> 头条JavaArrayList工作

头条JavaArrayList工作

1.概述

关于Java集合的小抄中是这样描述的:

以数组实现。节约空间,但数组有容量限制。超出限制时会增加50%容量,用System.arraycopy()复制到新的数组,因此最好能给出数组大小的预估值。默认第一次插入元素时创建大小为10的数组。

按数组下标访问元素—get(i)/set(i,e)的性能很高,这是数组的基本优势。

直接在数组末尾加入元素—add(e)的性能也高,但如果按下标插入、删除元素—add(i,e),remove(i),remove(e),则要用System.arraycopy()来移动部分受影响的元素,性能就变差了,这是基本劣势。

ArrayList是一个相对来说比较简单的数据结构,最重要的一点就是它的自动扩容,可以认为就是我们常说的“动态数组”。

来看一段简单的代码:

ArrayListStringlist=newArrayListString();

list.add("语文:99");

list.add("数学:98");

list.add("英语:");

list.remove(0);

在执行这四条语句时,是这么变化的:

其中,add操作可以理解为直接将数组的内容置位,remove操作可以理解为删除index为0的节点,并将后面元素移到0处。

2.add函数

当我们在ArrayList中增加元素的时候,会使用add函数。他会将元素放到末尾。具体实现如下:

publicbooleanadd(Ee){

ensureCapacityInternal(size+1);//IncrementsmodCount!!

elementData[size++]=e;

returntrue;

}

我们可以看到他的实现其实最核心的内容就是ensureCapacityInternal。这个函数其实就是自动扩容机制的核心。我们依次来看一下他的具体实现

privatevoidensureCapacityInternal(intminCapacity){

if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA){

minCapacity=Math.max(DEFAULT_CAPACITY,minCapacity);

}

ensureExplicitCapacity(minCapacity);

}

privatevoidensureExplicitCapacity(intminCapacity){

modCount++;

//overflow-consciouscode

if(minCapacity-elementData.length0)

grow(minCapacity);

}

privatevoidgrow(intminCapacity){

//overflow-consciouscode

intoldCapacity=elementData.length;

//扩展为原来的1.5倍

intnewCapacity=oldCapacity+(oldCapacity1);

//如果扩为1.5倍还不满足需求,直接扩为需求值

if(newCapacity-minCapacity0)

newCapacity=minCapacity;

if(newCapacity-MAX_ARRAY_SIZE0)

newCapacity=hugeCapacity(minCapacity);

//minCapacityisusuallyclosetosize,sothisisawin:

elementData=Arrays.copyOf(elementData,newCapacity);

}

也就是说,当增加数据的时候,如果ArrayList的大小已经不满足需求时,那么就将数组变为原长度的1.5倍,之后的操作就是把老的数组拷到新的数组里面。例如,默认的数组大小是10,也就是说当我们add10个元素之后,再进行一次add时,就会发生自动扩容,数组长度由10变为了15具体情况如下所示:

3.set和get函数

Array的put和get函数就比较简单了,先做index检查,然后执行赋值或访问操作:

publicEset(intindex,Eelement){

rangeCheck(index);

EoldValue=elementData(index);

elementData[index]=element;

returnoldValue;

}

publicEget(intindex){

rangeCheck(index);

returnelementData(index);

}

4.remove函数

publicEremove(intindex){

rangeCheck(index);

modCount++;

EoldValue=elementData(index);

intnumMoved=size-index-1;

if(numMoved0)

//把后面的往前移

System.arraycopy(elementData,index+1,elementData,index,

numMoved);

//把最后的置null

elementData[--size]=null;//cleartoletGCdoitswork

returnoldValue;

}

注释很清楚:

Removestheelementatthespecifiedpositioninthislist.Shiftsanysubsequentelementstotheleft(subtractsonefromtheirindices).









































北京白癜风治疗一般多少钱
北京治疗白癜风医院有哪些



转载请注明:http://www.jiaju1314.com/xxzl/936.html