关于ArrayList源码解读
关于ArrayList源码解读
1.ArrayList实现的相关接口以及各个接口的属性
1.ArrayList实现了List接口,具备List的属性
2.实现了RandomAccess接口,可以通过下标序号进行快速访问。
3.实现了Cloneable接口,能被克隆
4.实现了Serializable,支持序列化
2.ArrayList中各个成员变量的解释
1.private static final int DEFAULT_CAPACITY = 10;默认存储空间
2.private static final Object[] EMPTY_ELEMENTDATA = {};空动态数组
3.private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 空容量数组
4.transient Object[] elementData; 动态获取存储地址的elementData,因为被transient修饰,所以不能被序列化
5.private int size;数组中元素的个数
3.创建一个不设置初始容量的list集合的底层实现步骤
3.1 当创建一个没有设置初始容量的ArrayList时,默认会创建一个空的集合
3.2 当执行第一次添加操作时,默认会为list赋值初始容量10.
3.2.1 当添加一个元素的时候,集合的大小加一,执行**ensureCapacityInternal(minCapcity)**方法
3.2.2 进入方法首先回判断elemnntData是否等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA,如果是则和默认的容量10,进行比较,然后取其中较交大的一个
3.2.3 然后紧接着调用**ensureExplicitCapacity(minCapacity)**方法
我们可以清楚的看到有一个全局的modCount++在进行自增操作,madCount属性是继承AbstractList的记录了结构性改变的次数。结构性改变指的是那些修改了列表大小的操作,在迭代过程中可能会造成错误的结果。madCount交由迭代器(Iterator)和列表迭代器(ListIterator)使用,当进行next()、remove()、previous()、set()、add()等操作时,如果madCount的值意外改变,那么迭代器或者列表迭代器就会抛出ConcurrentModificationException异常。紧接着判断最小容量是否大于当前动态数组elementData的容量,如果大于则调用grow(minCapacity)方法进行设置动态数组的大小和将值拷贝进动态数组。
3.2.4 调用grow(int minCapacity)方法
将容量扩大1.5倍,执行了向右的位运算,然后将预期容量也就是newCapacity和最小容量进行比较,如果还不满足就将最小容量赋值给预期容量,如果预期容量减去MAX_ARRAY_SIZE,MAX_ARRAY_SIZE的值为int类型的最大值减去8,然后判断是否大于0,则进行一次hugeCapacity操作,先回判断是否会出现内存溢出,其实一般很少用到hugeCapacity操作。
3.2.5最后调用数组的Arrays.copyOf方法将数据和数组大小设置进elementData中。
4.ArrayList的特点
1.底层是以动态数组实现的。
2.增删比较慢,因为要重新创建一个数组然后再把值拷贝进新的数组。
st的特点
1.底层是以动态数组实现的。
2.增删比较慢,因为要重新创建一个数组然后再把值拷贝进新的数组。
3.查询快,因为实现了RandomAcces接口,支持下标查询。