容器(七):垂垂老矣Vector

容器(七):垂垂老矣Vector

标签: Java编程思想

  • 容器七垂垂老矣Vector
    • 一道面试题
    • 什么是Vector
    • Vector 成员变量
    • Vector 的构造方法
      • 默认无参构造器
      • 指定容量构造器
      • 指定容量和增长量的构造器
      • 包含集合的构造器
    • Vector中的扩容方法
    • Vector的添加元素的方法
      • 确保容量
    • 其他方法
    • Vector遍历
      • 随机访问
      • 迭代器
      • for循环
      • Enumeration循环
    • 总结


Vector是List家族里的老资格了,在JDK1.0,还没有List的时候,Vector就已经开始为Collection家族效力了,在JDK1.2以后,并入到List中。随着时间的变迁,这个第一代容器早已经打上了“不推荐使用”的标签。

一道面试题

之前看过一篇面经,问题是ArrayList和Vector的区别:

ArrayList,Vector主要区别为以下几点:

  1. Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比;
  2. ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍;
  3. Vector可以设置capacityIncrement,而ArrayList不可以,从字面理解就是capacity容量,Increment增加,容量增长的参数。

Vecotor唯一的优势就是线程安全,但是现在有Collections.synchronizedListt方法拿同步的List,因此不推荐使用Vector了。

什么是Vector

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

Vector 和 ArrayList 一样,都是继承自 AbstractList。它是 Stack 的父类。英文的意思是 “矢量”。

Vector 成员变量

//底层也是个数组
protected Object[] elementData;//数组元素个数
protected int elementCount;//扩容时增长数量,允许用户自己设置。如果这个值是 0 或者 负数,扩容时会扩大 2 倍,而不是 1.5
protected int capacityIncrement;//给定一个最大的容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

Vector 的构造方法

默认无参构造器

实际上是调用含参数的构造器,只是默认的数组容量为10:

//创建默认容量 10 的数组,同时增长量为 0 
public Vector() {this(10);}

指定容量构造器

实际上是调用指定容量和增长量的构造器,只是默认的增长量为0:

//创建一个用户指定容量的数组,同时增长量为 0 
public Vector(int capacity) {this(capacity, 0);
}

指定容量和增长量的构造器

我们通过构造函数可以看出,Vector的底层是一个Object类型的数组,指定了扩容时的增长量。

//创建指定容量大小的数组,设置增长量。如果增长量为非正数,扩容时会扩大两倍
public Vector(int initialCapacity, int capacityIncrement) {super();if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);this.elementData = new Object[initialCapacity];this.capacityIncrement = capacityIncrement;}

包含集合的构造器

//创建一个包含指定集合的数组
public Vector(Collectionextends E> c) {//转成数组,赋值elementData = c.toArray();elementCount = elementData.length;// c.toArray might (incorrectly) not return Object[] (see 6260652)//可能有这个神奇的 bug,用 Arrays.copyOf 重新创建、复制if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}

Vector中的扩容方法

与ArrayList.grow(int) 很相似,只是扩大量不同:

private void grow(int minCapacity) {// 原先的底层数组的大小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);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}

Vector的添加元素的方法

确保容量

检查数量,准备扩容

private void ensureCapacityHelper(int minCapacity) {if (minCapacity - elementData.length > 0)grow(minCapacity);
}

其他方法

因为Vector不怎么用了,而且方法很多,我就不想挨个去看源码了。要用的时候查阅API就好了

Vector遍历

Vector支持4种遍历方式。

随机访问

因为Vector实现了RandmoAccess接口,可以通过下标来进行随机访问。

for(int i = 0 ; i < vec.size() ; i++){  value = vec.get(i);  }  

迭代器

Iterator it = vec.iterator();  while(it.hasNext()){  value = it.next();   //do something  }  

for循环

for(Integer value:vec){  //do something  }  

Enumeration循环

Vector vec = new Vector<>();  Enumeration enu = vec.elements();  while (enu.hasMoreElements()) {  value = (Integer)enu.nextElement();  }  

总结

Vector 特点:

  • 底层由一个可以增长的数组组成
  • Vector 通过 capacity (容量) 和 capacityIncrement (增长数量) 来尽量少的占用空间
  • 扩容时默认扩大两倍
  • 最好在插入大量元素前增加 vector 容量,那样可以减少重新申请内存的次数
  • 通过 iterator 和 lastIterator 获得的迭代器是 fail-fast 的
  • 通过 elements 获得的老版迭代器 Enumeration 不是 fail-fast 的
    同步类,每个方法前都有同步锁 synchronized

Vector VS ArrayListde 共同点:

  • 都是基于数组
  • 都支持随机访问
  • 默认容量都是 10
  • 都有扩容机制

Vector VS ArrayListde 区别:

  • Vector 出生的比较早,JDK 1.0 就出生了,ArrayList JDK 1.2 才出来
  • Vector 比 ArrayList 多一种迭代器 Enumeration
  • Vector 是线程安全的,ArrayList 不是
  • Vector 默认扩容 2 倍,ArrayList 是 1.5

其实现在不管有没有线程安全都需求,都不推荐使用Vector。

ps:用心学习,喜欢的话请点赞 (在左侧哦)


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部