Vector源码浅析 底层结构+扩容机制 通俗易懂

1.5Vector源码解析

1.5.1无参构造器创建Vector

1.首先用无参构造器创建Vector对象,通过debug方式追溯源码
在这里插入图片描述

在Vector的无参构造器中会去调用有参构造器,并传入一个初始容量大小10,这就是我们所知道的,Vector如果没有指定初始容量,则默认容量大小为10,然后在public Vector(int initalCapacity)这个有参构造器中去调用带有两个参数的构造器。

在这里插入图片描述

public Vector(int initalCapacity,int capacityIncrement)这个构造器当中,会先判断初始化容量大小是否<0,如果<0则抛出异常,如果没有则初始化Object[] elementData 数组长度为initalCapacity,从这也可以看出Vector底层也是一个数组来存放元素。

在这里插入图片描述

2.执行vector.add()方法,进入add方法源码后,仍然有一个modCount变量来记录对集合的操作次数。接着执行ensureCapacityHelper()方法,传入参数为:当前元素个数+1。

在这里插入图片描述

进入ensureCapacityHelper()方法,会先判断当前所需的最小容量是否大于数组的长度,如果大于则需要进行扩容。第一次的时候添加一个元素的时候minCapacity为1,而数组 的长度为10,所以容量足够不会进入grow()方法。所以会回到上图中add()方法执行第783行代码,将元素添加到数组当中。这样就完成一次元素的添加

在这里插入图片描述

3.执行完10个元素的添加以后,可以发现当前vector集合当中已经有10个元素了,那么我们要执行vector.add(5),也就是添加第是一个元素,这个时候vector的容量已经不够了,所以会需要进行扩容,接着进行debug。
在这里插入图片描述

进入add()方法后,执行ensureCapacityHelper()方法,并且传入的参数为11

在这里插入图片描述

当进入到ensureCapacityHelper()方法之后,会进行if判断,这个时候我们所需的最小容量minCapacity为11,而这个时候的数组的长度为10,所以if为true,执行grow方法进行扩容。

在这里插入图片描述

进入到grow方法当中,可以会先把数组的长度赋值给oldCapacity,接着执行newCapacity的赋值,因为通过一开始创建对象使用的构造器可以知道capacityIncrement为0,所以newCapacity = oldCapacity + oldCapacity,这也就是Vector在没有指定扩容增幅的前提下,默认扩容大小为前一次的2倍

在这里插入图片描述

最后执行Arrays,copyOf把原始数组拷贝到新的数组,此时就可以发现elementData数组容量为20。

在这里插入图片描述

接着继续执行add()方法,将要添加的元素存入数组当中。这样就成功添加第11个元素,后面添加元素也都是按照这个规律。

在这里插入图片描述

1.5.2有参构造器创建Vector

1.可以使用带有两个参数的构造器进行Vector对象的创建。第一个参数为初始Capacity,第二个参数为每次容量扩容的增幅capacityIncrement。在上面使用无参构造器的时候,默认capacityIncrement=0

在这里插入图片描述

其他步骤都是一样的,就是在grow方法当中会有一些细微的差别。在第262行,newCapacity = oldCapacity + capacityIncrement,这个capacityIncrement就是我们通过有参构造器创建对象时指定的第二个参数大小。而以后的每次扩容都是原本的长度加上capacityIncrement的大小,就不是原来的2倍大小了。

在这里插入图片描述

1.5.3Vector和ArrayList比较

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_48244108/article/details/123516340
今日推荐