源码笔记-ArrayList

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的区别:

  1. 添加方法中包含synchronized关键字,同步操作;扩容只有在添加时产生。
  2. 扩容长度计算方法,判断是否初始化了capacityIncrement参数,如果增加值小于等于0,则采用原数组长度*2的方式进行扩容,如果增加值大于0,则采用原数组长度+增加值的方式进行扩容。
  3. 其它底层实现基本与ArrayList相同,底层操作的均为数组对象。

猜你喜欢

转载自blog.csdn.net/qq_42080073/article/details/112644637