js 解析php arraylist,从源码角度简单聊聊ArrayList

简介

ArrayList是一个可动态调整数组大小的集合类,其类图关系如下:

sgs_tc_news.php?req=B7zXw63s_1iS3QHCAaJ_egUY-Wb2wd8NuIypBzUM1_A=

ArrayList类图

sgs_tc_news.php?req=B7zXw63s_1iS3QHCAaJ_egUY-Wb2wd8NuIypBzUM1_A=

从属性与方法角度剖析ArrayList

属性解析

DEFAULT_CAPACITY:默认容量10,用于构造函数初始化与容量运算。

EMPTY_ELEMENTDATA:共享的空数组,调用ArrayList有参构造函数参数容量值为0(即一般考虑不再进行容量扩展)时赋给elementData。

DEFAULTCAPACITY_EMPTY_ELEMENTDATA:共享的空数组,与EMPTY_ELEMENTDATA区别在于该数组是用来容量运算的,调用ArrayList无参构造函数时会把该对象赋给elementData,添加元素时再重新计算扩容,所以一般建议使用有参构造函数赋予原始容量。

elementData:存储ArrayList的元素的数组缓冲区。size:ArrayList包含的元素数量,elementData数组的元素数量。MAX_ARRAY_SIZE:分配的最大数组大小,值为Integer.MAX - 8

方法解析add(E)添加元素

以下重新整理一下新增的的步骤:add()数组末尾添加元素

ensureCapacityInternal()确保内部的容量能满足所需最小容量minCapacity

calculateCapacity()根据数组所需的最小容量minCapacity进行容量计算

ensureExplicitCapacity()根据数组所需的最小容量minCapacity确保精确的容量

ensureExplicitCapacity()根据数组所需的最小容量minCapacity判断是否扩容,若需要则进行步骤6

grow()重新建一个至少可以容纳最小容量minCapacity的数组并进行数组元素拷贝,消耗大,所以建议一般使用有参构建函数创建列表时设置好容量

由上述流程可以看出,ArrayList的add(E e)方法在容量足以确保的情况下效率是很高的,直接将新元素赋予数组元素的末尾下标+1即可,复杂度仅为O(1)。add(int, E)增元素

该方法的主要核心在System.arraycopy()方法,该方法把elementData数组中的index位置起的size-index个元素(即index下标后的元素)复制到下标index+1,然后再把新的元素element赋到index下标位置。由于需要进行元素的位置逐个后移,所以性能耗费大,时间复杂度为O(n),n为指定位置后的元素数目。如在非末尾位置插入元素的操作较多,选择LinkedList效果会比ArrayList更好。addAll(Collection)添加元素

由上源码可以看到当添加集合元素时,也是需要进行数组拷贝的,不过是直接拷贝到列表数组末尾,时间复杂度由集合元素数目而定,即为O(n)。remove(Object)删元素

虽然删除元素的主要方面命名为fastRemove(),但从其代码依然可以看出这方法并不fast,指定位置删除元素后还要进行元素前移,性能耗费与指定位置添加差别不大,时间复杂度为O(n),n为指定位置后的元素数目。

如删除元素的操作较多,选择LinkedList效果会比ArrayList更好。set(int, E)改元素

替换指定下标数组元素,复杂度为O(1),效率高。get(int)查元素

根据下标获取数组元素,复杂度为O(1),效率高。

总结ArrayList有以下特点:添加元素性能因参数有所区别,但都需注意数组容量不足时ArrayList会进行扩容产生性能消耗add(E)在数组末尾添加元素,复杂度O(1)add(int, E)在数组指定位置添加元素,复杂度O(n),n为下标后的元素数目addAll(Collection)在数组末尾添加集合元素,复杂度O(n),n为集合中的元素数目删除元素慢,remove()删除元素,后面元素需逐个移动,复杂度O(n),n为下标后的元素数目更改效率高,set(index, E)直接根据下标替换数组元素,复杂度O(1)查询效率高,get(index)直接根据下标获取数组元素,复杂度O(1)添加元素性能因参数有所区别,但都需注意数组容量不足时ArrayList会进行扩容产生性能消耗add(E)在数组末尾添加元素,复杂度O(1)add(int, E)在数组指定位置添加元素,复杂度O(n),n为下标后的元素数目addAll(Collection)在数组末尾添加集合元素,复杂度O(n),n为集合中的元素数目

删除元素慢,remove()删除元素,后面元素需逐个移动,复杂度O(n),n为下标后的元素数目

更改效率高,set(index, E)直接根据下标替换数组元素,复杂度O(1)

查询效率高,get(index)直接根据下标获取数组元素,复杂度O(1)

综上,如果与指定下标元素增删操作更多的时候选择ArrayList会导致数组需要进行多次的元素移动,性能消耗十分大,该情况更适合使用LinkedList,因LinkedList增删元素时只需更改该元素上一个与下一个节点的指向即可,相当于从一个双向链表中摘除一个元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值