ArrayList
无参构造,默认创建长度为0的空数组;
第一次扩容时,长度扩容至10;
后续需要数组元素存满后再次扩容。
核心方法:
Arrays.copyOf()方法,涉及数组扩容时,用于copy数组。
System.arraycopy(Object src, int srcPos,Object dest, int destPos,int length)方法,Arrays.copyOf()方法底层也是调用该方法。
- src:源数组对象;
- srcPos:源数组copy起始坐标,默认0;
- dest:目标数组;
- destPos:目标数组存储起始坐标,默认0;
- length:copy的元素长度。
1、涉及Arrays.copyOf()方法包含:
构造方法:ArrayList(Collection<? extends E> c);
去掉末端空元素的方法:trimToSize();
克隆复制方法:clone();
转换数组方法:toArray();
转换数组带参方法:toArray(T[] a);
添加方法:add(E e);如果元素满了,涉及扩容。
添加指定下标位置的方法:add(int index, E element);
2、涉及System.arraycopy()方法包含:
移除指定下标方法:remove(int index);
移除指定元素方法:remove(Object o);移除第一个匹配的元素。
移除指定下标范围方法:removeRange(int fromIndex, int toIndex);
3、包含两个复制方法:
添加多个元素的方法:addAll(Collection<? extends E> c);扩容使用Arrays.copyOf()方法,复制元素使用System.arraycopy()方法;
添加指定下标多个元素的方法:addAll(int index, Collection<? extends E> c);
ArrayList扩容原理:
- 执行添加操作的时候,使用集合当前长度size+新增元素个数(参数:minCapacity)调用ensureCapacityInternal()方法;
- 如果是第一次添加的时候,集合元素为空的时候,minCapacity的值会和默认容量(10)取最大值,也就是10;
- 集合元素不为空的时候,则直接将传入的minCapacity用作参数进行扩容校验;
- 判断校验minCapacity-当前集合长度是否大于0;只有在集合中元素存满的时候,再次执行添加操作才会触发扩容。
- 获取一个新的容量长度,集合长度+集合长度右移1位;扩容效果约等于1.5倍。
- 新的容器长度小于传入的minCapacity长度,则取传入的长度。
- 新的容器长度大于Integer.MAX_VALUE - 8,则判断minCapacity长度,大于Integer.MAX_VALUE - 8则取Integer.MAX_VALUE,否则则取Integer.MAX_VALUE - 8。
- 调用Arrays.copyOf()方法,创建一个新长度的数组,并将元素从原集合中copy过去。
- 返回新的数组,赋值给当前集合对象。
Vector扩容原理和ArrayList的区别:
- 添加方法中包含synchronized关键字,同步操作;扩容只有在添加时产生。
- 扩容长度计算方法,判断是否初始化了capacityIncrement参数,如果增加值小于等于0,则采用原数组长度*2的方式进行扩容,如果增加值大于0,则采用原数组长度+增加值的方式进行扩容。
- 其它底层实现基本与ArrayList相同,底层操作的均为数组对象。