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

 

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

 

一、概述

我们都知道,在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<Integer> list = Collections.synchronizedList(new ArrayList<Integer>());
		
		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<Integer> 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】所示,进群的时候记得表明自己想要学习什么,不要用小号,这样小编才好给你们发定向资源,今天小编就免费送!~

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

 

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

猜你喜欢

转载自blog.csdn.net/qq_41552245/article/details/86220635
0条评论
添加一条新回复