java_集合体系之Vector详解、源码及示例——05

java_集合体系之Vector详解、源码及示例——05


一:Vector结构图


java_集合体系之Vector详解、源码及示例——05_第1张图片

简单说明:

        1、上图中虚线且无依赖字样、说明是直接实现的接口

        2、虚线但是有依赖字样、说明此类依赖与接口、但不是直接实现接口

        3、实线是继承关系、类继承类、接口继承接口

 

二:Vector类简介:


        1、Vector是内部是以动态数组的形式来存储数据的。

        2、Vector具有数组所具有的特性、通过索引支持随机访问、所以通过随机访问Vector中的元素效率非常高、但是执行插入、删除时效率比较地下、具体原因后面有分析。

        3、Vector实现了AbstractList抽象类、List接口、所以其更具有了AbstractList和List的功能、前面我们知道AbstractList内部已经实现了获取Iterator和ListIterator的方法、所以Vector只需关心对数组操作的方法的实现、

        4、Vector实现了RandomAccess接口、此接口只有声明、没有方法体、表示Vector支持随机访问。

        5、Vector实现了Cloneable接口、此接口只有声明、没有方法体、表示Vector支持克隆。

        6、Vector实现了Serializable接口、此接口只有声明、没有方法体、表示Vector支持序列化、即可以将Vector以流的形式通过ObjectOutputStream来写入到流中。

        7、Vector是线程安全的。


三:Vector API


        1、构造方法


Vector()	// 默认构造函数

Vector(int capacity)	// capacity是Vector的默认容量大小。当由于增加数据导致容量增加时,每次容量会增加一倍。

Vector(int capacity, int capacityIncrement)		// capacity是Vector的默认容量大小,capacityIncrement是每次Vector容量增加时的增量值。

Vector(Collection<? extends E> collection)		// 创建一个包含collection的Vector


        2、一般方法

 

synchronized boolean        add(E object)
             void           add(int location, E object)
synchronized boolean        addAll(Collection<? extends E> collection)
synchronized boolean        addAll(int location, Collection<? extends E> collection)
synchronized void           addElement(E object)
synchronized int            capacity()
             void           clear()
synchronized Object         clone()
             boolean        contains(Object object)
synchronized boolean        containsAll(Collection<?> collection)
synchronized void           copyInto(Object[] elements)
synchronized E              elementAt(int location)
             Enumeration<E> elements()
synchronized void           ensureCapacity(int minimumCapacity)
synchronized boolean        equals(Object object)
synchronized E              firstElement()
             E              get(int location)
synchronized int            hashCode()
synchronized int            indexOf(Object object, int location)
             int            indexOf(Object object)
synchronized void           insertElementAt(E object, int location)
synchronized boolean        isEmpty()
synchronized E              lastElement()
synchronized int            lastIndexOf(Object object, int location)
synchronized int            lastIndexOf(Object object)
synchronized E              remove(int location)
             boolean        remove(Object object)
synchronized boolean        removeAll(Collection<?> collection)
synchronized void           removeAllElements()
synchronized boolean        removeElement(Object object)
synchronized void           removeElementAt(int location)
synchronized boolean        retainAll(Collection<?> collection)
synchronized E              set(int location, E object)
synchronized void           setElementAt(E object, int location)
synchronized void           setSize(int length)
synchronized int            size()
synchronized List<E>        subList(int start, int end)
synchronized <T> T[]        toArray(T[] contents)
synchronized Object[]       toArray()
synchronized String         toString()
synchronized void           trimToSize()

        总结:相对与ArrayList而言、Vector是线程安全的、即他的有安全隐患的方法都使用了synchroized关键字、Vector中多定义一个构造方法、用于指定当Vector自动扩容时的增量大小、Vector是个很老的类、他其中的许多方法都不是必须的、比如addElement(E e)、setElement(E, int)其实完全可以用add(E e)、set(E, int)取代、所以Vector的API源码显的比较臃肿、基本现在已经不再推荐使用Vector了、可以使用经过处理后的ArrayList来代替多线程环境中的Vector。至于如何处理会在List总结中有说到。


四:Vector源码分析


package com.chy.collection.core;

import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess;

/** Vector:矢量集合、*/
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
	/** 保存Vector中元素的数组*/
    protected Object[] elementData;

    /** 保存Vector中元素的数组的容量、即数组的size*/
    protected int elementCount;

    /** 每次Vector自动扩容的增量*/
    protected int capacityIncrement;

    /** 默认版本号*/
    private static final long serialVersionUID = -2767605614048989439L;

    /** 使用指定的Vector容量和每次扩容的增量创建Vector*/
    public Vector(int initialCapacity, int capacityIncrement) {
		super();
	        if (initialCapacity < 0)
	            throw new IllegalArgumentException("Illegal Capacity: "+
	                                               initialCapacity);
		this.elementData = new Object[initialCapacity];
		this.capacityIncrement = capacityIncrement;
    }

    /** 使用指定的Vector容量创建Vector*/
    public Vector(int initialCapacity) {
    	this(initialCapacity, 0);
    }

    /** 使用默认的Vector容量创建Vector*/
    public Vector() {
    	this(10);
    }

    /** 使用指定的Collection创建Vector*/
    public Vector(Collection<? extends E> c) {
		elementData = c.toArray();
		elementCount = elementData.length;
		// c.toArray might (incorrectly) not return Object[] (see 6260652)
		if (elementData.getClass() != Object[].class)
		    elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

    /** 将Vector中的元素copy到传入的数组中*/
    public synchronized void copyInto(Object[] anArray) {
    	System.arraycopy(elementData, 0, anArray, 0, elementCount);
    }

    /** 将Vector的size与Vector中元素同步*/
    public synchronized void trimToSize() {
		modCount++;
		int oldCapacity = elementData.length;
		if (elementCount < oldCapacity) {
	            elementData = Arrays.copyOf(elementData, elementCount);
		}
    }

    /** 确保Vector的capacity最小不小于minCapacity*/
    public synchronized void ensureCapacity(int minCapacity) {
		modCount++;
		ensureCapacityHelper(minCapacity);
    }

    /** 确保Vector的capacity最小不小于minCapacity*/
    private void ensureCapacityHelper(int minCapacity) {
		int oldCapacity = elementData.length;
		if (minCapacity > oldCapacity) {
		    Object[] oldData = elementData;
		    int newCapacity = (capacityIncrement > 0) ?
			(oldCapacity + capacityIncrement) : (oldCapacity * 2);
	    	    if (newCapacity < minCapacity) {
			newCapacity = minCapacity;
		    }
	            elementData = Arrays.copyOf(elementData, newCapacity);
		}
    }

    /** 修改Vector的size、
     *  1、若传入的newSize > Vector中元素的个数、则将Vector的size修改成newSize、
     *  2、否则将Vector索引从newSize开始后面的元素都设置成null、并且将Vector的size修改成newSize
     */
    public synchronized void setSize(int newSize) {
		modCount++;
		if (newSize > elementCount) {
		    ensureCapacityHelper(newSize);
		} else {
		    for (int i = newSize ; i < elementCount ; i++) {
			elementData[i] = null;
		    }
		}
		elementCount = newSize;
    }

    /** 查看Vector的容量*/
    public synchronized int capacity() {
    	return elementData.length;
    }

    /** 查看Vector的size*/
    public synchronized int size() {
    	return elementCount;
    }

    /** 查看Vector是否为空*/
    public synchronized boolean isEmpty() {
    	return elementCount == 0;
    }

    /** 返回一个包含Vector中所有元素的Enumeration、Enumeration提供用于遍历Vector中所有元素的方法、
     *	相对与Iterator、ListIterator而言他不是fail-fast机制 
     */
    public Enumeration<E> elements() {
		return new Enumeration<E>() {
		    int count = 0;
	
		    public boolean hasMoreElements() {
		    	return count < elementCount;
		    }
	
		    public E nextElement() {
				synchronized (Vector.this) {
				    if (count < elementCount) {
					return (E)elementData[count++];
				    }
				}
				throw new NoSuchElementException("Vector Enumeration");
		    }
		};
    }

    /** 查看Vector是否包含o*/
    public boolean contains(Object o) {
    	return indexOf(o, 0) >= 0;
    }

    /** 返回o所在的索引*/
    public int indexOf(Object o) {
    	return indexOf(o, 0);
    }

    /** 从index处向后搜索o所在的索引值、没有则返回-1*/
    public synchronized int indexOf(Object o, int index) {
		if (o == null) {
		    for (int i = index ; i < elementCount ; i++)
			if (elementData[i]==null)
			    return i;
		} else {
		    for (int i = index ; i < elementCount ; i++)
			if (o.equals(elementData[i]))
			    return i;
		}
		return -1;
    }

    /** 从后向前查找o所在索引值*/
    public synchronized int lastIndexOf(Object o) {
    	return lastIndexOf(o, elementCount-1);
    }

    /** 从尾部index处向前查找o所在索引值、没有则返回-1*/
    public synchronized int lastIndexOf(Object o, int index) {
        if (index >= elementCount)
            throw new IndexOutOfBoundsException(index + " >= "+ elementCount);

		if (o == null) {
		    for (int i = index; i >= 0; i--)
			if (elementData[i]==null)
			    return i;
		} else {
		    for (int i = index; i >= 0; i--)
			if (o.equals(elementData[i]))
			    return i;
		}
		return -1;
    }

    /** 返回idnex处的元素*/
    public synchronized E elementAt(int index) {
		if (index >= elementCount) {
		    throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
		}
        return (E)elementData[index];
    }

    /** 返回第一个元素*/
    public synchronized E firstElement() {
		if (elementCount == 0) {
		    throw new NoSuchElementException();
		}
		return (E)elementData[0];
    }

    /** 返回最后一个元素*/
    public synchronized E lastElement() {
		if (elementCount == 0) {
		    throw new NoSuchElementException();
		}
		return (E)elementData[elementCount - 1];
    }

    /** 将Vector的index处的元素修改成E*/
    public synchronized void setElementAt(E obj, int index) {
		if (index >= elementCount) {
		    throw new ArrayIndexOutOfBoundsException(index + " >= " +
							     elementCount);
		}
		elementData[index] = obj;
    }

    /** 删除Vector的index处元素*/
    public synchronized void removeElementAt(int index) {
		modCount++;
		if (index >= elementCount) {
		    throw new ArrayIndexOutOfBoundsException(index + " >= " +
							     elementCount);
		}
		else if (index < 0) {
		    throw new ArrayIndexOutOfBoundsException(index);
		}
		int j = elementCount - index - 1;
		if (j > 0) {
		    System.arraycopy(elementData, index + 1, elementData, index, j);
		}
		elementCount--;
		elementData[elementCount] = null; /* to let gc do its work */
    }

    /** 将obj插入Vector的index处、新增元素的后面的原来的元素后移1位、效率相对LinkedList低的原因*/
    public synchronized void insertElementAt(E obj, int index) {
		modCount++;
		if (index > elementCount) {
		    throw new ArrayIndexOutOfBoundsException(index
							     + " > " + elementCount);
		}
		ensureCapacityHelper(elementCount + 1);
		System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
		elementData[index] = obj;
		elementCount++;
    }

    /** 将obj追加到Vector末尾*/
    public synchronized void addElement(E obj) {
		modCount++;
		ensureCapacityHelper(elementCount + 1);
		elementData[elementCount++] = obj;
    }

    /** 删除obj、若成功返回true、失败返回false*/
    public synchronized boolean removeElement(Object obj) {
		modCount++;
		int i = indexOf(obj);
		if (i >= 0) {
		    removeElementAt(i);
		    return true;
		}
		return false;
    }

    /** 删除Vector所有元素*/
    public synchronized void removeAllElements() {
        modCount++;
		// Let gc do its work
		for (int i = 0; i < elementCount; i++)
		    elementData[i] = null;
		elementCount = 0;
    }

    /** 克隆Vector*/
    public synchronized Object clone() {
		try {
		    Vector<E> v = (Vector<E>) super.clone();
		    v.elementData = Arrays.copyOf(elementData, elementCount);
		    v.modCount = 0;
		    return v;
		} catch (CloneNotSupportedException e) {
		    // this shouldn't happen, since we are Cloneable
		    throw new InternalError();
		}
    }

    /** 将Vector转化成Object[]*/
    public synchronized Object[] toArray() {
        return Arrays.copyOf(elementData, elementCount);
    }

    /** 将Vector转换成T[]、相对与上面方法、对返回数组做了转型*/
    public synchronized <T> T[] toArray(T[] a) {
        if (a.length < elementCount)
            return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());

	System.arraycopy(elementData, 0, a, 0, elementCount);

        if (a.length > elementCount)
            a[elementCount] = null;

        return a;
    }

    // Positional Access Operations

    /** 获取idnex处元素*/
    public synchronized E get(int index) {
		if (index >= elementCount)
		    throw new ArrayIndexOutOfBoundsException(index);
	
		return (E)elementData[index];
    }

    /** 将index处元素设置成element、返回oldElement*/
    public synchronized E set(int index, E element) {
		if (index >= elementCount)
		    throw new ArrayIndexOutOfBoundsException(index);
	
		Object oldValue = elementData[index];
		elementData[index] = element;
		return (E)oldValue;
    }

    /** 将e追加到Vector末尾处*/
    public synchronized boolean add(E e) {
		modCount++;
		ensureCapacityHelper(elementCount + 1);
		elementData[elementCount++] = e;
	        return true;
    }

    /** 删除o*/
    public boolean remove(Object o) {
        return removeElement(o);
    }

    /** 将element添加到index处、后面的所有元素后移一位*/
    public void add(int index, E element) {
        insertElementAt(element, index);
    }

    /** 删除index处元素、返回oldElement*/
    public synchronized E remove(int index) {
		modCount++;
		if (index >= elementCount)
		    throw new ArrayIndexOutOfBoundsException(index);
		Object oldValue = elementData[index];
	
		int numMoved = elementCount - index - 1;
		if (numMoved > 0)
		    System.arraycopy(elementData, index+1, elementData, index,
				     numMoved);
		elementData[--elementCount] = null; // Let gc do its work
	
		return (E)oldValue;
    }

    /** 删除所有元素*/
    public void clear() {
        removeAllElements();
    }

    // Bulk Operations

    /** 是否包含Collection c?*/
    public synchronized boolean containsAll(Collection<?> c) {
        return super.containsAll(c);
    }

    /** 将Collection c所有元素追加到Vector末尾*/
    public synchronized boolean addAll(Collection<? extends E> c) {
		modCount++;
	        Object[] a = c.toArray();
	        int numNew = a.length;
		ensureCapacityHelper(elementCount + numNew);
	        System.arraycopy(a, 0, elementData, elementCount, numNew);
	        elementCount += numNew;
		return numNew != 0;
    }

    /** 将Vector中所有与Collection c相同的元素删除*/
    public synchronized boolean removeAll(Collection<?> c) {
        return super.removeAll(c);
    }

    /** 求Vector与传入的Collection的元素的交集*/
    public synchronized boolean retainAll(Collection<?> c)  {
        return super.retainAll(c);
    }

    /** 将Collection所有元素追加到Vector从index处开始的位置、后面的原来是元素后移c.size()个位置*/
    public synchronized boolean addAll(int index, Collection<? extends E> c) {
		modCount++;
		if (index < 0 || index > elementCount)
		    throw new ArrayIndexOutOfBoundsException(index);
	
	        Object[] a = c.toArray();
		int numNew = a.length;
		ensureCapacityHelper(elementCount + numNew);
	
		int numMoved = elementCount - index;
		if (numMoved > 0)
		    System.arraycopy(elementData, index, elementData, index + numNew,
				     numMoved);
	
	        System.arraycopy(a, 0, elementData, index, numNew);
		elementCount += numNew;
		return numNew != 0;
    }

    /** 判断Vector中是否包含o*/
    public synchronized boolean equals(Object o) {
        return super.equals(o);
    }

    /** 返回hash值*/
    public synchronized int hashCode() {
        return super.hashCode();
    }

    public synchronized String toString() {
        return super.toString();
    }

    /** 返回Vector子集*/
    public synchronized List<E> subList(int fromIndex, int toIndex) {
        return Collections.synchronizedList(super.subList(fromIndex, toIndex),
                                            this);
    }

    /** 删除部分元素*/
    protected synchronized void removeRange(int fromIndex, int toIndex) {
		modCount++;
		int numMoved = elementCount - toIndex;
	        System.arraycopy(elementData, toIndex, elementData, fromIndex,
	                         numMoved);
	
		// Let gc do its work
		int newElementCount = elementCount - (toIndex-fromIndex);
		while (elementCount != newElementCount)
		    elementData[--elementCount] = null;
    }

    /** 将Vector写入到ObjectOutputStream流中、注意:没有对应的ObjectInputStream来读取*/
    private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException
    {
    	s.defaultWriteObject();
    }
}

        总结:从Vector源码可以看出、Vector内部是通过动态数组来存储数据、从中我们也可以很容易的找到Vector的几个特性:

        1、有序:如果不指定元素存放位置、则元素将依次从Object数组的第一个位置开始放、如果指定插入位置、则会将元素插入指定位置、后面的所有元素都后移

        2、可重复:从源码中没有看到对存放的元素的校验

        3、随机访问效率高:可以直接通过索引定位到我们要找的元素

        4、自动扩容:ensureCapacity(intminCapacity)方法中会确保数组的最小size、当不够时会将原来的容量变为oldCapacity *2、之后那这个值与传入的最小容量进行比较、若还小于传入的最小容量值、则使用传入的最小容量值。

        5、变动数组元素个数(即添加、删除数组元素)效率低、在增删的操作中我们常见的一个函数: System.arraycopy()、他是将删除、或者添加之后、原有的元素进行移位、这是需要较大代价的。

        6、有些方法完全没有必要、比如对元素的增删改查的、后缀为Element的完全可以使用从List中继承的增删改查来替代。

        7、对于Vector得到的Iterator、ListIterator是fail-fast机制、针对此现象、Vector提供了自己特有的遍历方式Enumeration、此迭代不是fail-fast机制的。用于并发线程的环境中.

        8、在使用ObjectOutputStream时、会先将Vector的capacity写入到流中、他与ArrayList不同的是:Vector没有ObjectInputStream用于读取写入的Vector。

 

五:Vector示例


        因为使用集合、我们最关心的就是使用不同集合的不同方法的效率问题、而在这些中、最能体现效率问题的关键点是对集合的遍历、所以对于示例、分为两部分:第一部分是关于集合的不同的遍历方法的耗时示例、第二部分是集合的API的使用示例。


        1、遍历方法:


        01)使用Iterator遍历Vector

		Iterator<String> it = v.iterator();
		while(it.hasNext()){
			String s = it.next();
		}

        02)使用ListIterator遍历Vector

                ListIterator<String> it = v.listIterator();
		while(it.hasNext()){
			String s = it.next();
		}

        03)使用随机访问(即for(int i=0;i<xxx; i++)这种形式称为随机访问)遍历Vector

		for (int i = 0; i < v.size(); i++) {
			String s = v.get(i);
		}

        04)使用增强for循环遍历Vector

		for(String str : v){
			String s = str;
		}

        05)使用Enumeration迭代Vector

		Enumeration<String> e = v.elements();
		while(e.hasMoreElements()){
			String s = e.nextElement();
		}

        06)示例

 

package com.chy.collection.example;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;

@SuppressWarnings("unused")
public class EragodicVector {
	private static Vector<String> v ;
	//静态块初始化一个较大的Vector
	static{
		v = new Vector<String>();
		for (int i = 0; i < 300000; i++) {
			v.add("a");
		}
	}
	
	/**
	 * 使用Iterator迭代
	 */
	private static void testIterator(){
		long start = currentTime();
		Iterator<String> it = v.iterator();
		while(it.hasNext()){
			String s = it.next();
		}
		long end = currentTime();
		System.out.println("iterator time : " + (end - start) + "ms");
	}

	/**
	 * 使用ListIterator迭代
	 */
	private static void testListIterator(){
		long start = currentTime();
		ListIterator<String> it = v.listIterator();
		while(it.hasNext()){
			String s = it.next();
		}
		long end = currentTime();
		System.out.println("ListIterator time : " + (end - start) + "ms");
	}
	
	/**
	 * 使用foreach循环
	 */
	private static void testForeache(){
		long start = currentTime();
		for(String str : v){
			String s = str;
		}
		long end = currentTime();
		System.out.println("ListIterator time : " + (end - start) + "ms");
	}
	
	/**
	 * 使用Enumeration迭代
	 */
	private static void testEnumeration(){
		long start = currentTime();
		Enumeration<String> e = v.elements();
		while(e.hasMoreElements()){
			String s = e.nextElement();
		}
		long end = currentTime();
		System.out.println("Enumeration time : " + (end - start) + "ms");
	}
	
	/**
	 * 使用随机访问迭代
	 */
	private static void testRandomAccess(){
		long start = currentTime();
		for (int i = 0; i < v.size(); i++) {
			String s = v.get(i);
		}
		long end = currentTime();
		System.out.println("RandomAccess time : " + (end - start) + "ms");
	}
	
	private static long currentTime() {
		return System.currentTimeMillis();
	}
	
	public static void main(String[] args) {
		testIterator();
		testListIterator();
		testRandomAccess();
		testEnumeration();
		testForeache();
	}
	
}

        结果及说明:

iterator time : 32ms
ListIterator time : 31ms
RandomAccess time : 16ms
Enumeration time : 31ms
ListIterator time : 31ms
        

        与ArrayList类似、使用随机访问效率最高、其他的都基本相似。

        2、API演示


package com.chy.collection.example;

import java.util.Arrays;
import java.util.Vector;

import com.chy.collection.bean.Student;

@SuppressWarnings("unused")
public class VectorTest {

	/**
	 * 测试Vector添加元素方法、与size有关的方法
	 */
	private static void testAddSizeElements(){
		//初始化含有字符串“abcdefg”的Vector
		Vector<String> v = new Vector<String>();
		v.add("a");
		v.add(v.size(), "b");
		v.addElement("c");
		String[] strArray = {"d", "e"};
		Vector<String> v1 = new Vector<String>(Arrays.asList(strArray));
		v.addAll(v.size(), v1);
		//在结尾处插入一个元素“f”
		v.insertElementAt("f", v.size());
		v.addElement("g");
		println(v.toString());
		
		//查看当前Vector的size和容量
		println("v size : " + v.size() + "  v capacity : " + v.capacity());
		//确保当前Vector的容量不小于10
		v.ensureCapacity(10);
		println("v size : " + v.size() + "  v capacity : " + v.capacity());
		//确保当前Vector的size与容量同步
		v.trimToSize();
		println("v size : " + v.size() + "  v capacity : " + v.capacity());
		//设置Vector的size
		v.setSize(15);
		println("v size : " + v.size() + "  v capacity : " + v.capacity());
		println(v.toString());
		//确保当前Vector的size与容量同步
		v.trimToSize();
		println("v size : " + v.size() + "  v capacity : " + v.capacity());
		
		/*
		 * 结果说明:
		 * 1、size指的是Vector中所具有的元素的个数、包括值为null的元素
		 * 2、capacity指的是Vector所能容纳的最大的元素个数、
		 * 3、ensureCapacity(int minCapacity)方法是确保Vector最小的容纳元素个数不小于传入的参数
		 * 4、setSize()是改变当前Vector中元素个数
		 * 5、trimToSize()	都是取size的值
		 */
	}
	
	/**
	 * 测试包含、删除方法
	 */
	private static void testContainsRomve(){
		//初始化包含学号从1到10的十个学生的ArrayList
		Vector<Student> v1 = new Vector<Student>();
		Student s1 = new Student(1,"chy1");
		Student s2 = new Student(2,"chy2");
		Student s3 = new Student(3,"chy3");
		Student s4 = new Student(4,"chy4");
		v1.add(s1);
		v1.add(s2);
		v1.add(s3);
		v1.add(s4);
		for (int i = 5; i < 11; i++) {
			v1.add(new Student(i, "chy" + i));
		}
		System.out.println(v1);
		
		//初始化包含学号从1到4的四个学生的ArrayList
		Vector<Student> v2 = new Vector<Student>();
		v2.add(s1);
		v2.add(s2);
		v2.add(s3);
		v2.add(s4);
		//查看v1中是否包含学号为1的学生
		println(v1.contains(s1));
		//查看v1中是否包含学号为5的学生、因为下面学号为5的学生是新创建的对象、所以不包含
		//从这里可以看出、v1中保存的是对象的引用
		println(v1.contains(new Student(5, "chy5")));
		//查看v1中是否包含集合v2
		println(v1.containsAll(v2));
		//修改v2中第一元素的值
		v2.set(0, new Student(10, "chy10"));
		//查看v1是否包含v2
		println(v1.containsAll(v2));
		
		
		//删除当前Vector第一个元素
		println(v1.remove(0));
		//删除当前Vector第一个元素
		println(v1);
		
		//如果s3存在、则删除s3
		if(v1.contains(s3)){
			println(v1.remove(s3));
		}
		//删除v1中所包含的v2的元素
		v1.removeAll(v2);
		println(v1);
		
		//求v1与v2的交集
		v1.retainAll(v2);
		println(v1);
		//删除v1中所有元素
		v1.removeAllElements();
		//v1.clear();作用相同
		println(v1);
	}

	/**
	 * 测试Vector查找、修改元素方法
	 */
	private static void testGetSet(){
		//初始化包含"abcde"的Vector
		Vector<String> v1 = new Vector<String>();
		v1.add("a");
		v1.add("b");
		v1.add("c");
		v1.add("d");
		v1.add("e");
		//获取"a"元素的索引
		println("从前向后找 第一个 a 元素索引  : " + v1.indexOf("a") + "从后向前找:" + v1.lastIndexOf("a"));
		//获取第一个、最后一个元素
		println("first element : " + v1.firstElement() + " last element : " + v1.lastElement());
		
		//从前或者后面指定的索引开始查找 "a"的索引值
		println("from start: " + v1.indexOf("a", 1) + " from end: " + v1.lastIndexOf("a", v1.size() - 1));
		
		//将Vector中“b” 修改成“a”
		if(v1.indexOf("b") != -1){
			v1.set(v1.indexOf("b"), "a");
		}
		println(v1);
	}

	/**
	 * 测试数组集合之间的转换
	 */
	private static void testConvertBetweenArrayAndVector(){
		//Array2Vector
		String[] strArray = {"a", "b" ,"c", "d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
		Vector<String> v = (Vector<String>)Arrays.asList(strArray);//作为String[]使用时会报错、因为此方法的返回值是Object、将一个Object强转成Vector<String>会报异常
		Vector<String> v1 = new Vector<String>(Arrays.asList(strArray));//可正常使用、在Vector构造方法中会根据strArray的类型返回对应类型的Vector。
		
		//Vector2Array
		String[] strArray1 = (String[])v1.toArray();//作为String[]使用时会报错、因为v1.toArray()返回的是Object[]、强转会出错
		String[] strArray2 = v1.toArray(new String[0]);//可正常使用、v1.toArray(new String[0])会根据传入的参数的类型、将返回结果转换成对应类型
	}
	
	private static void println(Object str) {
		System.out.println(str.toString());
	}
	
	
	
	public static void main(String[] args) {
//		testAddSizeElements();
//		testContainsRomve();
//		testGetSet();
	}
}

总结:

        对于Vector、是一个比较古老的类、相对于ArrayList而言、它通过将许多方法使用synchronized修饰来保证线程安全性、但是保证线程安全是要代价的、这也使得他的效率并没有ArrayList高、所以在单线程环境中不推荐使用Vector、即使在并发情况也也不推荐使用Vector、而是使用被包装后的ArrayList !


更多内容:java_集合体系之总体目录——00


你可能感兴趣的:(vector,Collection,iterator,enumeration,Vector框架图)