Java集合之Vector源码分析

来源:互联网 发布:知乎海贼王回答集锦 编辑:程序博客网 时间:2024/04/30 06:04

前面,我们已经学习了ArrayList,LinkedList,我们接着按着集合框架图学习–Vector。
说好的先膜拜一下网上的Java集合框架图
这里写图片描述

Vector(jdk 1.8)

Vector和ArrayList大同小异,都是动态数组,Vector和ArrayList差别很小,因此本文不会按照ArrayList那样分析,只是简单揭开Vector的面纱,对比一下和ArrayList的区别。

继承体系

这里写图片描述

Vector和ArrayList的继承体系是一样的。
Vector实现RandmoAccess接口,即提供了随机访问功能,提供提供快速访问功能。在Vector我们可以直接访问元素。
Vector 实现了Cloneable接口,支持clone()方法,可以被克隆。
Vector 实现了Serializable接口,可以被序列化。

数据结构

元 素 作 用 protected Object[] elementData Vector是基于数组的一个实现,elementData就是底层的数组 protected int elementCount Vector里面元素的个数 protected int capacityIncrement Vector

扩容每次的增量

在ArrayList 中 底层数组是的声明有transient 关键字,而在Vector中没有。

Vector 中有一个capacityIncrement元素,这个是Vector 每次扩容时候的增量,这个可以在通过构造函数设置,在ArrayList,正常情况下每次扩容后是原来的1.5倍。

构造方法

1、执行初始容量大小,和每次扩容的增量

    public Vector(int initialCapacity, int capacityIncrement) {        super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        this.elementData = new Object[initialCapacity];        this.capacityIncrement = capacityIncrement;    }

2、默认增量值为0

    public Vector(int initialCapacity) {        this(initialCapacity, 0);    }

3、默认数组大小为10

    public Vector() {        this(10);    }

扩容

    private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?                                         capacityIncrement : oldCapacity);        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);        elementData = Arrays.copyOf(elementData, newCapacity);    }

如果增量为0,那么就扩大一倍,扩容后的大小是原来的两倍。

添加元素

    public synchronized boolean add(E e) {        modCount++;        ensureCapacityHelper(elementCount + 1);        elementData[elementCount++] = e;        return true;    }

这里只看Vector的一个添加方法,其余方法和ArrayList 方法类似,就不一样列出来了。
在Vector 方法中 多了一个synchronized 关键,在前面我们就学习过synchronized 关键字,它是用来进行线程同步的,被synchronized 修饰的方法将会被串行执行,也就是说是线程安全的,因此可以看出Vector是线程安全的,而ArrayList是非线程的

序列化

Vector的熟悉中没有被transient 所修饰,因此都可以进行默认的序列化,在Vector中我们还是发现了writeObject 方法

    private void writeObject(java.io.ObjectOutputStream s)            throws java.io.IOException {        final java.io.ObjectOutputStream.PutField fields = s.putFields();        final Object[] data;        synchronized (this) {            fields.put("capacityIncrement", capacityIncrement);            fields.put("elementCount", elementCount);            data = elementData.clone();        }        fields.put("elementData", data);        s.writeFields();    }

Vector中的writeObject 和ArrayList中的writeObject 目的是一样的,减小不必要的数据序列化。因为elementData 也许并没有装满,完全序列化elementData 在网络传输中是浪费流量的。
ArrayList 中是手动的将elementData 进行序列化,Vector 严格来说不算手动,只是在序列化是动了点手脚。
Vector 中 将elementData添加到需要序列化的域,添加的elementData 是原elementData克隆的结果,克隆后的elementData 只有存在数据的地方,但是可能会包含空值(Vector 和ArrayList一样可以存放空置),ArrayList中也是如此,只是实现方式不一样而已。打个比方:把数据放入文件,有两种方式,一种写个程序把数据写到文件,还有一种就是可视化打开文件,然后把数据粘贴进行,完成。最后效果都是一样的,只是过程不一样而已。

Vector中没有readObject ,因为Vector的属性中没有被transient 所修饰,因此反序列化时就不要干预,自动就可以完成,而在ArrayList中因为elementData 是被transient 修饰的,不能自动序列化,需要我们手动设置数据。

总结

Vector的 的分析很简单,因为和ArrayList基本上是差不多的。

  1. Vector 存储的数据允许为空
  2. Vector 允许存储重复数据
  3. Vector 存储数据是有序 (有序的意思是读取数据的顺序和存放数据的顺序是否一致)
  4. Vector 线程安全(对底层数组的操作进行了同步)
  5. Vector 在扩容时会更加增量来进行扩容,没有设置增量,则扩大一倍。
原创粉丝点击