容器-Vector容器类(四)
-
Vector底层也是用数组实现的,相关的方法都增加了同步检查,线程安全,效率低
Vector容器类和ArrayList容器类的区别就是在线程,ArrayList是线程不安全的,效率高
- Vector的添加元素,因为都是继承List接口,所以Vector类和ArrayList类的方法都是差不多的,要想了解更多的方法,直接参照Array-list类。
public class VectorTest { public static void main(String[] args) { //实例化Vector List<String> v=new Vector<>(); v.add("a"); v.add("b"); v.add("c"); for (int i=0;i<v.size();i++){ System.out.println(v.get(i)); } System.out.println("--------------------"); for (String str:v){ System.out.println(str); } } }
-
Vector的源码分析,在JDK1.8之后,Vector和ArryList的区别就是:
-
第一,ArryList在创建一个数组长度为10的数组,采用的是延时的初始化,而Vector采用的是立即初始化
-
第二,ArryList是以1.5倍在扩容,而Vector是以2倍在扩容
-
先建立一个Vector对象,用Ctrl+鼠标右键进入源代码
public class VectorTest { public static void main(String[] args) { //实例化Vector List<String> v=new Vector<>();//Vector对象,用Ctrl+鼠标右键进入源代码 v.add("a"); v.add("b"); v.add("c"); for (int i=0;i<v.size();i++){ System.out.println(v.get(i)); } System.out.println("--------------------"); for (String str:v){ System.out.println(str); } } }
-
Vector的结构和成员变量
public class Vector<E>//继承了AbstractList<E>抽象类,实现了List<E>接口 extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { /** * The array buffer into which the components of the vector are * stored. The capacity of the vector is the length of this array buffer, * and is at least large enough to contain all the vector's elements. * * <p>Any array elements following the last element in the Vector are null. * * @serial */ protected Object[] elementData; /** * The number of valid components in this {@code Vector} object. * Components {@code elementData[0]} through * {@code elementData[elementCount-1]} are the actual items. * * @serial */ protected int elementCount; /** * The amount by which the capacity of the vector is automatically * incremented when its size becomes greater than its capacity. If * the capacity increment is less than or equal to zero, the capacity * of the vector is doubled each time it needs to grow. * * @serial */ protected int capacityIncrement;//计算容量增长,没给初始化就是0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -2767605614048989439L; /** * Constructs an empty vector with the specified initial capacity and * capacity increment. * * @param initialCapacity the initial capacity of the vector * @param capacityIncrement the amount by which the capacity is * increased when the vector overflows * @throws IllegalArgumentException if the specified initial capacity * is negative */
-
然后,我们看无参构造方法
/** * Constructs an empty vector so that its internal data array * has size {@code 10} and its standard capacity increment is * zero. */ public Vector() { //没有指定长度,都是默认10的 this(10); }
-
继续看this这个构造方法
/** * Constructs an empty vector with the specified initial capacity and * with its capacity increment equal to zero. * * @param initialCapacity the initial capacity of the vector * @throws IllegalArgumentException if the specified initial capacity * is negative */ public Vector(int initialCapacity) { this(initialCapacity, 0);//initialCapacity的值是10,capacityIncrement是0 }
-
在继续this,看这个构造方法
/** * Constructs an empty vector with the specified initial capacity and * capacity increment. * * @param initialCapacity the initial capacity of the vector * @param capacityIncrement the amount by which the capacity is * increased when the vector overflows * @throws IllegalArgumentException if the specified initial capacity * is negative */ public Vector(int initialCapacity, int capacityIncrement) { //initialCapacity是10 super(); if (initialCapacity < 0)//initialCapacity是10,不执行这个条件 throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; //初始化之后,nitialCapacity是10,就是一个数组为10的长度,赋值给elementData=10,所以这就是立即初始化的方式。 this.capacityIncrement = capacityIncrement;// capacityIncrement还是0 }
-
-
用add的方法添加元素
- 用Ctrl+鼠标左键进入源代码
boolean add(E e);
-
用Ctrl+Alt+鼠标左键,选择Vector类的add方法
boolean add(E e);
-
Vector类的add方法的源码
/** * Appends the specified element to the end of this Vector. * * @param e element to be appended to this Vector * @return {@code true} (as specified by {@link Collection#add}) * @since 1.2 */ public synchronized boolean add(E e) { //synchronized这就它解决线程安全的,把并行化的方式改成串行画的方式 modCount++;//跟ArrayList的那个相似的计时器 ensureCapacityHelper(elementCount + 1);//判断是否需要扩容的方法 elementData[elementCount++] = e; return true; }
-
什么时候会扩容,我们看下ensureCapacityHelpe的方法
/** * This implements the unsynchronized semantics of ensureCapacity. * Synchronized methods in this class can internally call this * method for ensuring capacity without incurring the cost of an * extra synchronization. * * @see #ensureCapacity(int) */ private void ensureCapacityHelper(int minCapacity) { //minCapacity现在是10,当你变成11的时候,就会满足下面的条件minCapacity - elementData.length=11-10=1>0,进行扩容 // overflow-conscious code if (minCapacity - elementData.length > 0)//触发是否扩容的条件 grow(minCapacity); }
-
假设minCapacity是11了,怎么扩容,grow(int minCapacity)是扩容的方法。
private void grow(int minCapacity) { //minCapacity是11 // overflow-conscious code int oldCapacity = elementData.length; //elementData.length是10,所以oldCapacity是10 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //根据三目运算符来,capacityIncrement是0,0不会大于0,执行oldCapacity,所以oldCapacity是10,所以newCapacity=10+10=20 if (newCapacity - minCapacity < 0) //20-11大于0不执行 newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0)//也是不会执行的 newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); //就来最重要的了,elementData是10,newCapacity是20,经过copyOf之后,elementData就会变成20,就实现了扩容。 //minCapacity时21时,oldCapacity是20, newCapacity=20+20=40,经过copyOf之后,elementData就变成了40 //所以也就是已2倍扩容了 }