java基础提高之Vector

253 阅读3分钟

        上一篇中我们介绍了ArrayList。其实在ArrayList的源码注释中就明确的指出了ArrayList这个类大致的等于Vector除了ArrayList是不同步的。那么现在趁热打铁,我们开始学习一下Vector。

结构分析

RandomAccess

        这个Vector同样也实现了RandomAccess这个标记类,同ArrayList一样,代表能够高效的实现随机访问。

存储结构

同上篇一样,我们也是先来看看Vector的属性

可以看到,属性相比ArrayList的少了,那现在我们来看看这几个东西是干啥的。

  1. elementData: 这个elementData的作用跟ArrayList中的一样,都是用来存储元素的,这个数组的长度也就是这个Vector的容量。
  2. elementCount: 这个和ArrayList中的size差不多都是用来记录存储元素的数量的,比如现在Vector中有2个元素,这个elemetnCount=2;
  3. capacityIncrement: 这个属性就有点意思了,我们可以发现ArrayList中没有跟这个类似的东西,其实在我个人认为这也是一个Vector与ArrayList之间的一个不同点。 那这个属性是用来干啥的呢? 从名字我们可以猜出大概,容量增量,其实就是扩容的时候用来定义扩容多少的,我们会在下面扩容的内容中详细解说。

很简单,属性就上面那三个。我们可以发现Vector的底层存储结构就是一个数组

基本方法

        对于Vector的基本方法,不做太多介绍,其实就是对数组的操作,主要,对于数组的移位操作使用的System.arraycopy来完成,还有一个特点相比较ArrayList来说就是他的许多方法都有一个关键字synchronized。这就是为什么说Vector是同步的原因。我们看一下下面的图来体会一下:

subList

我们重点说一下subList方法,同时也是对ArrayList的一个补充。

subList返回的List是基于这个Vector或者ArrayList的的,也就是说,对subList返回的List进行的操作的结果最后会反映到源Vector或ArrayList上的,我们用代码来体会一下:

public class TestMain {
    public static void main(String[] args){
        System.out.println("===============ArrayList=================");
        List<String> list = new ArrayList<>(Arrays.asList("1", "2", "3", "4", "5"));
        List<String> subList = list.subList(0,2);
        subList.add("我是subList插入的");
        list.forEach(value ->System.out.print(value+" ,") );
        System.out.println();
        System.out.println("===============Vector==================");
        Vector<String> vector = new Vector<>(Arrays.asList("1", "2", "3", "4", "5"));
        List<String> subVector = vector.subList(0,2);
        subVector.add("我是subVector插入的");
        vector.forEach(value ->System.out.print(value+" ,"));
    }
}

运行结果如下:

扩容机制

有上一节的铺垫,我们不做太多无用的的查看,直接看扩容的核心代码:

这就是Vector扩容的核心代码,看到与ArrayList的大同小异,不过这里确实多了一个这个东西,

在计算新的容量的时候,看了capacityIncrement的值是不是大于0,这个就是我们所说Vector与ArrayList扩容的不同处了,Vector可以自定义增长系数,控制需要扩容时增长的容量大小。当没有指定时默认增长为原来的两倍,与ArrayList一样,由于数组不能动态增大,所以是使用Arrays.copyOf重新生成了一个数组。

总结

  1. Vector内部使用数组存储元素,由于在方法时加了synchronized,所以性能比ArrayList低,但是是线程安全的。
  2. Vector扩容机制与ArrayList有些不同,不同之处在于Vector可以指定增长系数capacityIncrement,当不指定这个增长系数或者capacityIncrement为0的情况下默认扩容为原来的两倍。