ArrayList源码解析
@auther 无忧少年
@creatTime 2020/07/10
一、ArrayList结构
顾名思义,ArrayList的结构实际就是一个Object[]
。所以它的特性很明显,插入一个元素的时候,是耗时是一个常量时间O(1),在插入n个元素的时候,需要的时间就是O(n)。其他的操作中,运行的时间也是一个线性的增长(与数组中的元素个数有关)。
二、ArrayList源码解析
2.1 ArrayList类的继承关系
其中值得一提的是RandomAccess
接口,该接口的目的是这么说的:
List
实现所使用的标记接口,用来表明其支持快速(通常是固定时间)随机访问。此接口的主要目的是允许一般的算法更改其行为,从而在将其应用到随机或连续访问列表时能提供良好的性能。
**对于顺序访问的list,比如LinkedList,**使用Iterator访问会比使用for-i来遍历list更快。这一点其实很好理解,当对于LinkedList使用get(i)的时候,由于是链表结构,所以每次都会从表头开始向下搜索,耗时肯定会多。
**对于实现RandomAccess这个接口的类,如ArrayList,**我们在遍历的时候,使用for(int i = 0; i < size; i++)
来遍历,其速度比使用Iterator快(接口上是这么写的)。但是笔者看源码的时候,Iterator里使用的也是i++
,这种遍历,无非是增加了fail-fast判断,估计就是这个导致了性能的差距,但是没有LinkedList这么大。笔者循环了 1000 * 1000 次,贴出比较结果,仅供参考,有兴趣的朋友们可以试一试,循环次数越多越明显:
----------now is arraylist----------
使用Iterator迭代一共花了19ms时间
使用for-i迭代一共花了9ms时间
----------now is linkedList----------
使用Iterator迭代一共花了17ms时间
使用for-i迭代一共花了434ms时间
而其继承的AbstractList主要给ArrayList提供了诸如add
,get
,set
,remove
的集合方法。2.2
2.2 ArrayList的成员变量
//初始化默认容量
private static final int DEFAULT_CAPACITY = 10;
// 空对象数组
private static final Object[] EMPTY_ELEMENTDATA = {
};
// 默认容量的空对象数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
// 实际存储对象的数组
transient Object[] elementData;
// 存储的数量