文章目录

  • 什么是Vector?
  • Vector与ArrayList有什么区别?
    • 相同点
    • 不同点
  • Vector中的一些成员变量
  • Vector中的构造方法有哪些?
    • 一、Vector(int initialCapacity, int capacityIncrement)
    • 二、Vector(int initialCapacity)
    • 三、Vector()
    • 四、Vector(Collection<? extends E> c)
  • Vector的扩容
    • grow
      • hugeCapacity()
  • Vector中常用的操作
    • add()
      • ensureCapacityHelper()
    • get()
    • remove()
  • 为什么说Vector是线程安全的?
  • Vector的简单使用

什么是Vector?

Vector是一个可以实现自动增长的对象数组(简称动态数组),可以随着向量元素的增加而动态地增长,实际上是一种动态顺序表的应用

Vector与ArrayList有什么区别?

相同点

Vector:

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

ArrayList:

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

可以看到 Vector 和 ArrayList 都继承了 AbstractList 类,并且都实现了 List、RandomAccess、Cloneable、Serializable 接口,都可以存储 null 值

不同点

这样看来 Vector 和 ArrayLis 的功能是一样的,那为什么会有 Vector 这个动态数组呢?ArrayList不也是动态数组吗?因为 Vector 是基于线程安全的,而ArrayList不是线程安全的,所以有很多人都会说 Vector 是线程安全的 ArrayList

ArrayList默认的扩容倍数是1.5倍(关于ArrayList的扩容可以看下这篇文章 深入理解ArrayList),而Vector默认扩容的倍数是2倍

Vector中的一些成员变量

// 底层实现是数组
protected Object[] elementData;// 数组元素个数
protected int elementCount;// 扩容时增长数量
protected int capacityIncrement;// 序列ID
private static final long serialVersionUID = -2767605614048989439L;

Vector中的构造方法有哪些?

一、Vector(int initialCapacity, int capacityIncrement)

// 创建输入参数为初始化容量和增长量参数的构造方法
public Vector(int initialCapacity, int capacityIncrement) {super();// 如果向量的初始化容量为负数,则抛出 IllegalArgumentException 异常if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);// 将初始化容量的长度作为Object数组(elementData)的实际长度this.elementData = new Object[initialCapacity];// 初始化增量参数this.capacityIncrement = capacityIncrement;
}

二、Vector(int initialCapacity)

// 创建一个初始化容量且增量为0的数组
public Vector(int initialCapacity) {this(initialCapacity, 0);
}

三、Vector()

// 创建一个初始化容量为10,且增量为0的空数组
public Vector() {this(10);
}

四、Vector(Collection<? extends E> c)

// 创建一个包含指定集合中元素的数组,这些元素会按集合的迭代器返回元素的顺序排列
public Vector(Collection<? extends E> c) {// 将集合元素(c)转换为数组并赋值给Object数组(elementData)elementData = c.toArray();// 获取数组的长度elementCount = elementData.length;// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)// 将c中的元素拷贝到Object数组(elementData)elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}

Vector的扩容

grow

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 传入一个最小容量
private void grow(int minCapacity) {// overflow-conscious code// oldCapacity翻译过来就是旧的容量,把Object数组(elementData)的长度赋值给旧的容量int oldCapacity = elementData.length;// newCapacity翻译过来就是新的容量,当增量 > 0 // 那么新的容量就等于旧的容量+增量,否则为旧的容量的2倍(这里跟ArrayList中的不太一样)int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);// 如果新的容量 - 实际需要的容量 < 0if (newCapacity - minCapacity < 0)// 将实际需要的容量赋值给新的容量newCapacity = minCapacity;// 如果新的容量比数组最大的容量还要大if (newCapacity - MAX_ARRAY_SIZE > 0)// 那么就扩容为巨大容量newCapacity = hugeCapacity(minCapacity);// 用Arrays.copyOf复制elementData = Arrays.copyOf(elementData, newCapacity);
}

hugeCapacity()

巨大容量 hugeCapacity() 方法源码如下(跟ArrayList的一样):

private static int hugeCapacity(int minCapacity) {// 如果传入的实际容量 < 0,则抛出 OutOfMemoryError 异常if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;
}

为了能更好的理解,我们把这段代码搬过来运行测试一下:

/*** 自己新建的类:测试 hugeCapacity 方法的作用*/
public class HashDemo {private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}public static void main(String[] args) {// 假设这里传入10int i = hugeCapacity(10);System.out.println("Integer Max Value is " + Integer.MAX_VALUE);System.out.println("hugeCapacity return is " + i);}
}

输出结果为:

可以看到 Integer的最大值为 2147483647,最大值 - 8 = 2147483639,也就是说不管我们传入的数字是多少,经过 hugeCapacity() 运算后得到的结果都是 最大值 - 8 = 2147483639

Integer Max Value is 2147483647
hugeCapacity return is 2147483639

我们再把传入的数字改大一点,比如我们传入一个比 最大值 - 8 = 2147483639 还要大的数字

public static void main(String[] args) {// 假设这里传入10int i = hugeCapacity(2147483640);System.out.println("Integer Max Value is " + Integer.MAX_VALUE);System.out.println("hugeCapacity return is " + i);
}

输出结果为:

可以看到当穿传入的数字比 最大值 - 8 = 2147483639 还要大的数字的时候,返回的值就是 Integer 的最大值

Integer Max Value is 2147483647
hugeCapacity return is 2147483647

这样讲下来应该比较好理解了

Vector中常用的操作

add()

// 采用同步的方式往向量中添加元素
public synchronized boolean add(E e) {modCount++;// 因为添加的元素需要动态地扩容,所以调用 ensureCapacityHelper 方法的时候需要 + 1ensureCapacityHelper(elementCount + 1);// 采用顺序表添加元素,赋值长度+1elementData[elementCount++] = e;return true;
}

ensureCapacityHelper()

private void ensureCapacityHelper(int minCapacity) {// overflow-conscious code// 如果elementCount + 1 - 数组的容量 > 0 if (minCapacity - elementData.length > 0)// 则进行扩容操作(上面已讲解grow方法)grow(minCapacity);
}

get()

// 返回向量中指定位置的元素
public synchronized E get(int index) {// 如果下标 > 数组元素,则抛出 ArrayIndexOutOfBoundsException 异常if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);// 否则返回指定索引的对象return elementData(index);
}

remove()

protected transient int modCount = 0;public synchronized E remove(int index) {// 修改次数+1modCount++;// 如果下标大于元素的数量,则抛出 ArrayIndexOutOfBoundsException 异常if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);// 使用下标获取对应的旧值E oldValue = elementData(index);// 计算删除元素后需要移动补位的元素的数量int numMoved = elementCount - index - 1;// 如果这个数量 > 0if (numMoved > 0)// 拷贝元素System.arraycopy(elementData, index+1, elementData, index,numMoved);// 删除元素elementData[--elementCount] = null; // Let gc do its work// 返回旧值return oldValue;
}

为什么说Vector是线程安全的?

可以看到Vector的操作都是使用synchronized关键字进行同步的,也就是说是线程安全的,由于Vector是同步的,所以效率要比ArrayList低

Vector的简单使用

创建一个Vector向量,添加元素

public class HashDemo {public static void main(String[] args) {Vector<String> vector = new Vector<>();vector.add("ArrayList");vector.add("HashMap");vector.add("ConcurrentHashMap");vector.add("LinkedList");vector.add("LinkedHashMap");System.out.println(vector);}
}

输出结果为:

[ArrayList, HashMap, ConcurrentHashMap, LinkedList, LinkedHashMap]

使用迭代器输出结果

public class HashDemo {public static void main(String[] args) {Vector<String> vector = new Vector<>();vector.add("ArrayList");vector.add("HashMap");vector.add("ConcurrentHashMap");vector.add("LinkedList");vector.add("LinkedHashMap");Iterator<String> iterator = vector.iterator();while (iterator.hasNext()){System.out.println(iterator.next()); // 这里一定要加上next(),不然会出现死循环}}
}

输出结果为:

ArrayList
HashMap
ConcurrentHashMap
LinkedList
LinkedHashMap

深入理解 Vector相关推荐

  1. Neither shaken nor stirred(DFS理解+vector存图)

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=2013 题目理解: 给定n个点的有向图: 下面n行,第一个数字表示点权,后面一个数字m表示 ...

  2. Why Vector Clock are Easy or Hard?

    通过实际例子来阐述vector clock其实是容易理解的, easy 同样通过实际例子来描述在使用vector clock时会遇到哪些难以解决的问题, hard Why Vector Clocks ...

  3. vector嵌套vector嵌套pair

    vector< vector<pair<int, int> > >的用法 通过简单的例子来理解vector和vector的嵌套 第一层vector< vect ...

  4. C++标准库vector及迭代器

    vector是同一种对象的集合,每个对象都有一个对应的整数索引值.和string对象一样,标准库将负责管理与存储元素相关的类存.引入头文件 #include<vector> 1.vecto ...

  5. 关于STL中vector容器的一些总结

    第一个总结来自于http://www.jb51.net/article/41648.htm,第二个来自于http://www.cppblog.com/totti1006/archive/2009/09 ...

  6. vector容器用法详解

    vector类称作向量类,它实现了动态数组,用于元素数量变化的对象数组.像数组一样,vector类也用从0开始的下标表示元素的位置:但和数组不同的是,当vector对象创建后,数组的元素个数会随着ve ...

  7. vector的简单介绍

    1.vector的简单介绍 vector作为STL提供的标准容器之一,是经常要使用的,有很重要的地位,并且使用起来也是灰常方便.vector又被称为向量,vector可以形象的描述为长度可以动态改变的 ...

  8. C++中vector用法详解

    1.vector的简单介绍 vector作为STL提供的标准容器之一,是经常要使用的,有很重要的地位,并且使用起来也是灰常方便.vector又被称为向量,vector可以形象的描述为长度可以动态改变的 ...

  9. 【C++】手把手教你写出自己的vector类

    在上一篇博客中,我们学习了vector 的基本使用,以及 迭代器的失效问题: [C++]深入理解vector类(一) 今天我们来模拟实现以下vector类. 目录 成员变量 接口实现 构造函数 迭代器 ...

最新文章

  1. 针对Java开发者的持续交付完整实施指南 | 内含福利
  2. 基于SOA架构---ServiceProxy定义
  3. .NET Core log4net 使用
  4. 【FastJSON】解决FastJson中“$ref 循环引用”的问题
  5. mybatis源码分析(方法调用过程)
  6. 从C++到.NET 揭开多态的面纱
  7. Mybatis中的缓存详解
  8. Kafka : FileNotFoundException索引文件丢失 xxx.index (No such file or directory)
  9. centos6下安装git
  10. Audition报错:“无法应用设备设置,因为发生了以下错误:MME设备内部错误“
  11. JSP基础--J2EE赢在起跑线
  12. 一步一步学Repast 第四章——分析SimpleModel
  13. 王道计算机考研图书勘误表公布!
  14. 2017年度优秀软件工程造价师等评选通知
  15. asp.net中commandname应用
  16. VB读写远程Mysql数据库
  17. WPF控件模板和数据模板的区别
  18. 爬虫攻守道 - 2023最新 - Python Selenium 实现 - 数据去伪存真,正则表达式谁与争锋 - 爬取某天气网站历史数据
  19. 为什么计算机领域没有诺贝尔奖,为什么没有数学家获得诺贝尔奖
  20. 搜狐邮箱打开第三方邮件客户端登录功能及设置独立密码方法

热门文章

  1. 科技创新变革全新趋势
  2. 计算机可用网络连接不上,电脑网络连接不可用?学会这招,轻松解决
  3. 如何在网页上生成验证码?
  4. 求共同好友和好友推荐系统
  5. 数据结构课程设计(C语言实现)
  6. 怎样把Audio cd光盘里的歌曲文件复制到硬盘里
  7. 知名猎头告诉你员工离职,企业招聘时的猎头费用,谁来买单?
  8. 2020第十一届蓝桥杯10月份省赛真题(JavaB组题解)
  9. 用adb卸载安卓手机系统内置的应用
  10. Vue+SpringBoot+ElementUI实战学生管理系统-8.班级管理模块