一、vector简介 

  Vector 可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。不过,Vector 的大小是可以增加或者减小的,以便适应创建 Vector 后进行添加或者删除操作。

  Vector 实现 List 接口,继承 AbstractList 类,所以我们可以将其看做队列,支持相关的添加、删除、修改、遍历等功能。

  Vector 实现 RandmoAccess 接口,即提供了随机访问功能,提供提供快速访问功能。在 Vector 我们可以直接访问元素。

  Vector 实现了 Cloneable 接口,支持 clone() 方法,可以被克隆。

  Vector 是线程安全的,同步的

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

二、属性解析

  Vector 提供了 elementData , elementCount, capacityIncrement 三个成员变量。

  elementData :”Object[] 类型的数组”,它保存了 Vector 中的元素。按照 Vector 的设计 elementData 为一个动态数组,可以随着元素的增加而动态的增长,其具体的增加方式后面提到(ensureCapacity 方法)。如果在初始化 Vector 时没有指定容器大小,则使用默认大小为 10.

  elementCount:Vector 对象中的有效组件数。

  capacityIncrement:向量的大小大于其容量时,容量自动增加的量。如果在创建 Vector 时,指定了 capacityIncrement 的大小;则,每次当 Vector 中动态数组容量增加时>,增加的大小都是 capacityIncrement。如果容量的增量小于等于零,则每次需要增大容量时,向量的容量将增大一倍。

三、vector的构造函数

    /**
         * 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。
         */
         public Vector() {
                this(10);
         }

        /**
         * 构造一个包含指定 collection 中的元素的向量,这些元素按其 collection 的迭代器返回元素的顺序排列。
         */
        public Vector(Collection<? extends E> c) {
            elementData = c.toArray();
            elementCount = elementData.length;
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, elementCount,
                        Object[].class);
        }

        /**
         * 使用指定的初始容量和等于零的容量增量构造一个空向量。
         */
         public Vector(int initialCapacity) {
            this(initialCapacity, 0);
        }

        /**
         *  使用指定的初始容量和容量增量构造一个空的向量。
         */
        public Vector(int initialCapacity, int capacityIncrement) {
            super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                  initialCapacity);
            this.elementData = new Object [initialCapacity];
            this.capacityIncrement = capacityIncrement;
        }

四、源码解析

  4.1添加 add()

  public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);//确认容量大小,若超过,进行扩容
        elementData[elementCount++] = e;//将e元素添加至末尾
        return true;
    }
 private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
/**
         * 进行扩容操作
         * 如果此向量的当前容量小于minCapacity,则通过将其内部数组替换为一个较大的数组俩增加其容量。
         * 新数据数组的大小姜维原来的大小 + capacityIncrement,
         * 除非 capacityIncrement 的值小于等于零,在后一种情况下,新的容量将为原来容量的两倍,不过,如果此大小仍然小于 minCapacity,则新容量将为 minCapacity。
         */
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;//当前容器大小
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
 /*
             * 新容器大小
             * 若容量增量系数(capacityIncrement) > 0,则将容器大小增加到capacityIncrement
             * 否则将容量增加一倍
             */
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
//判断是否超出最大范围
private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

  对于 Vector 整个的扩容过程,就是根据 capacityIncrement 确认扩容大小的,若 capacityIncrement <= 0 则扩大一倍,否则扩大至 capacityIncrement 。当然这个容量的最大范围为 Integer.MAX_VALUE即,2^32 – 1,所以 Vector 并不是可以无限扩充的。

  4.2 删除 remove(Object o)

    /**
         * 从Vector容器中移除指定元素E
         */
        public boolean remove(Object o) {
            return removeElement(o);
        }

        public synchronized boolean removeElement(Object obj) {
            modCount++;
            int i = indexOf(obj);   //计算obj在Vector容器中位置
            if (i >= 0) {
                removeElementAt(i);   //移除
                return true;
            }
            return false;
        }

        public synchronized void removeElementAt(int index) {
            modCount++;     //修改次数+1
            if (index >= elementCount) {   //删除位置大于容器有效大小
                throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
            }
            else if (index < 0) {    //位置小于 < 0
                throw new ArrayIndexOutOfBoundsException(index);
            }
            int j = elementCount - index - 1;
            if (j > 0) {
                //从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
                //也就是数组元素从j位置往前移
                System.arraycopy(elementData, index + 1, elementData, index, j);
            }
            elementCount--;   //容器中有效组件个数 - 1
            elementData[elementCount] = null;    //将向量的末尾位置设置为null
        }

因为 Vector 底层是使用数组实现的,所以它的操作都是对数组进行操作,只不过其是可以随着元素的增加而动态的改变容量大小,其实现方法是是使用 Arrays.copyOf 方法将旧数据拷贝到一个新的大容量数组中。

集合家族——Vector的更多相关文章

  1. Collection集合家族

    集合家族 数组:存储相同类型的多个元素 对象:存储不同类型的多个元素 集合:存储多个不同类型的对象 List List继承自Collection接口,是有序可重复的集合. 它的实现类有:ArrayLi ...

  2. java集合之vector容器

    学完ArrayList和LinkedList之后,我们接着学习Vector.第1部分 Vector介绍第2部分 Vector数据结构第3部分 Vector源码解析(基于JDK1.6.0_45)第4部分 ...

  3. java集合之Vector向量基础

    Vector向量: vector类似动态数组,向量和数组类似,但是数组容量一旦确定不可更改,而向量的容量可变.向量只可以保存任何类型对象且容量不限制,数组对元素类型无限制但是容量有限. 适用场合:向量 ...

  4. Java基础系列 - JAVA集合ArrayList,Vector,HashMap,HashTable等使用

    package com.test4; import java.util.*; /** * JAVA集合ArrayList,Vector,HashMap,HashTable等使用 */ public c ...

  5. java学习笔记之集合家族2

    集合体系 一.数据结构 List集合储存数据结构 <1>堆栈结构 特点:先进后出 <2>队列结构 特点:先进先出 <3>数组结构 特点:查询快,增删慢 <4& ...

  6. Java集合之Vector

    Vector是矢量队列,它继承了AbstractList,实现了List. RandomAccess, Cloneable, java.io.Serializable接口. Vector接口依赖图: ...

  7. java-Collection集合、List集合、Vector集合和迭代器Iterator、ListIterator的使用

    1.对象数组的概述和使用 * A:案例演示 * 需求:我有5个学生,请把这个5个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息. * Student[] arr = new Student ...

  8. Java之集合(四)Vector和Stack

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7296023.html 1.前言 本章介绍Java集合List中的Vector和其子类Stack.Vector类是 ...

  9. 集合家族——List集合汇总

    一.概述 List继承了Collection,是有序的列表. 可重复数据 实现类有ArrayList.LinkedList.Vector.Stack等 ArrayList是基于数组实现的,是一个数组队 ...

随机推荐

  1. Pycharm 配置houdini

    一.houdini开发环境配置 1.添加Python可执行文件 2.设置代码自动补全 刚刚添加的Python.exe,右侧点击加号,依次添加以上长方形中的文件,路径会根据个人安装路径有所变化,后面的目 ...

  2. 【USB】struct usb_device_id 结构体详解

    struct usb_device_id { /* which fields to match against? */ __u16 match_flags; //说明使用哪种匹配方式 /* Used ...

  3. 解决python在cmd运行时导入包失败,出现错误信息 "ModuleNotFoundError: No module named ***"

    1.下图为我的自动化测试工程结构图 我通过运行run.bat批处理文件,调用cmd控制台运行start_run.py来开始我的自动化测试,但是出现如下错误: 大家可能知道我们的工程在IDE(Pycha ...

  4. javascript 的惯性运动

    移动端的惯性运动,最早来自 ios 的专利.用于手指滑动,离开屏幕之后,屏幕内容继续滚动.更有动态感. 这里,以 pc 端,鼠标横向(沿x轴) 拖拽的,惯性计算.移动端同理 具体代码如下: <! ...

  5. C#通讯框架改写

    现有项目是利用C#的socket与PLC进行实时通讯,PLC有两种通讯模式——常规采集&高频采集. 其中常规采集大概在10ms左右发送一次数据,高频采集大概在2ms左右发送一次数据. 现有代码 ...

  6. linux pthread多线程编程模板

    pthread_create() 创建线程,pthread_join()让线程一直运行下去. 链接时要加上-lpthread选项. pthread_create中, 第三个参数为线程函数,定义如下: ...

  7. linux--查看磁盘空间大小使用情况

    1. linux查看磁盘空间大小命令 df -h Df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息, 命令格式: df -hl  显示格式为:  文件系统 容量  ...

  8. win10环境安装配置Nginx

    前言: 参考 https://blog.csdn.net/kisscatforever/article/details/73129270 Nginx的应用场景      1. http服务器.Ngin ...

  9. 运行时异常与受检异常有何异同、error和exception有什么区别

    1.运行时异常与受检异常有何异同? 异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生.受检异常跟程序 ...

  10. Flutter——GridView组件(网格列表组件)

    GridView组件的常用参数: 名称 类型 说明 scrollDirection Axis 滚动方法 padding EdgeInsetsGeometry 内边距 resolve bool 组件反向 ...