美文网首页IT技术篇
Java容器类源码-Vector的最全的源码分析(一)

Java容器类源码-Vector的最全的源码分析(一)

作者: 游戏原画设计 | 来源:发表于2019-01-10 11:07 被阅读1次

    一、概述

    我们都知道,在Java的Collections包含了List和Set,而List里面有ArrayList、LinkedList、还有Vector,对于很多Java初学者来说,前面两个比较常用,ArrayList查询效率比较高(底层是数组实现),而LinkedList的增删效率比较高(底层是双向链表实现)。那么Vector是什么呢?它和ArrayList、LinkedList一样,支持有序可重复地存放单列数据。它底层实现和ArrayList类似,都是数组实现,因此在技术面试中, 面试官比较喜欢拿ArrayList和Vector进行比较。尽管Vector在Java1.2之后进行了优化更新,但是Java官方还是推荐在不需要考虑线程安全的情况下,优先使用ArrayList。

    二、Vector和ArrayList的对比

    那么,Vector和ArrayList既然都是数组实现,它们到底有什么区别呢?通过对比它们的源码,可以总结出以下两个区别:

    (1) Vector的所有方法都是有synchronized关键字的,即每一个方法都是同步的,所以在使用起来效率会非常低,但是保证了线程安全;而ArrayList的全部方法都是非同步的,所以相对Vector的效率会更高,所以它是线程不安全的。

    (2) ArrayList在每次扩容时都是增加当前容量的1.5倍,而Vector在扩容时都是增加当前容量的两倍。

    综上,Vector在增删改查等API上的实现都是和ArrayList类似甚至是相同的,所以如果你看了ArrayList的源码,那么Vector的源码你肯定是一下就看懂了,如果你还没看ArrayList的源码,请移步到《Java容器类源码-ArrayList的最全的源码分析》。所以在不需要考虑线程安全时,Java官方推荐我们使用ArrayList,那么,如果线程不安全时呢?我们应该怎么选择?我们都知道,Java在Collections类中给我们提供了同步ArrayList的方法public static <T> List<T> synchronizedList(List<T> list)。它可以帮助我们实现同步ArrayList,但是你通过看synchronizedList的实现就会知道,它其实是创建了一个新的类叫做SynchronizedList,它其实只是对ArrayList的增删改查等常用方法加了synchronized字段,所以它的效率其实和Vector是一样的,这个也在我们后面讲到的subList()源码里面得到印证,不信,我们在代码里面测试一下:

    /**

    * 测试使用Collections.synchronizedList调用增、删、改三个API操作50000个数据,求100次的平均时间

    *

    */

    public class QTest {

    public static void main(String[] args) {

    long totalTime = 0;

    for (int i = 0; i < 100; i++) {

    totalTime += new QTest().getTime();

    }

    System.out.println("Collections.synchronizedList() 平均耗时:" + (totalTime / 100));

    }

    public long getTime() {

    List list = Collections.synchronizedList(new ArrayList());

    long startTime = System.currentTimeMillis();

    for (int i = 0; i < 50000; i++) {

    list.add(i * 10); // 增加

    }

    for (int i = 0; i < 50000; i++) { // 修改

    list.set(i, i);

    }

    for (int i = 0; i < list.size(); i++) { // 删除

    list.remove(i);

    }

    long endTime = System.currentTimeMillis();

    System.out.println("Collections.synchronizedList()消耗时间:" + (endTime - startTime));

    return endTime - startTime;

    }

    }

    /**

    * 测试使用Vector调用增、删、改三个API操作50000个数据,求100次的平均时间

    *

    */

    public class PTest {

    public static void main(String[] args) {

    long totalTime = 0;

    for (int i = 0; i < 100; i++) {

    totalTime += new QTest().getTime();

    }

    System.out.println("vector 平均耗时:" + (totalTime / 100));

    }

    public long getTime() {

    Vector vector = new Vector<>();

    long nStartTime = System.currentTimeMillis();

    for (int i = 0; i < 100000; i++) {

    vector.add(i * 10); // 增加

    }

    for (int i = 0; i < 100000; i++) { // 修改

    vector.set(i, i);

    }

    for (int i = 0; i < vector.size(); i++) { // 删除

    vector.remove(i);

    }

    long nEndTime = System.currentTimeMillis();

    System.out.println("vector消耗时间:" + (nEndTime - nStartTime));

    return nEndTime - nStartTime;

    }

    }

    这两段代码其实就是对同步的ArrayList进行增、删、改50000条数据,并重复100次,求平均时间。通过运行,在我的电脑(每台电脑的运行速度不一样)里Collections.synchronizedList的100次平均消耗时间是:129ms,而Vector的100次平均消耗时间是:130ms。在需要考虑线程安全时,你是用Vector和Collections.synchronizedList初始化的ArrayList大概效率是差不多的。所以,Vector也并非毫无用武之地,那么这次我们就一起探究一下Vector的源码。

    ---------------------

    每天都在分享文章,也每天都有人想要我出来给大家分享下怎么去学习Java。大家都知道,我们是学Java全栈的,大家就肯定以为我有全套的Java系统教程。没错,我是有Java全套系统教程,进扣裙【47】974【9726】所示,进群的时候记得表明自己想要学习什么,不要用小号,这样小编才好给你们发定向资源,今天小编就免费送!~

    “我们相信人人都可以成为一个程序员,现在开始,找个师兄,带你入门,学习的路上不再迷茫。这里是ja+va修真院,初学者转行到互联网行业的聚集地。"

    相关文章

      网友评论

        本文标题:Java容器类源码-Vector的最全的源码分析(一)

        本文链接:https://www.haomeiwen.com/subject/vuiorqtx.html