Vector&Stack源码阅读笔记

Vector

  与ArrayList类似,底层是数组Object[] elementData),但是Vector线程安全的(每个方法都synchronized长度不固定,元素有序、可重复可以存null由于要保证线程安全,所以效率会比ArrayList低。默认初始容量为10,容量不足时默认2倍扩容,触发自动扩容后,不能自动减容,需手动减容(使用trimToSize方法)。

 

构造方法

Vector<String> vector = new Vector<>();       // 1.不指定默认初始容量为10,默认2倍扩容
Vector<String> vector1 = new Vector<>(20);    // 2.指定初始容量为20,默认2倍扩容
Vector<String> vector2 = new Vector<>(20,5);  // 3.指定初始容量为20,每次扩容增加5
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
Vector<String> vector3 = new Vector<>(list);  // 4.利用指定的Collection实现类对象(list)构造

 

常用方法

        vector.addElement("a");              // 尾部增加元素
        vector.add("a");                     // 尾部添加元素(返回true或false)

        vector.insertElementAt("b",1);     // 指定索引插入元素,其他元素后移
        vector.add(1,"b");               // 指定索引插入元素,其他元素后移(实际上调用了insertElementAt方法)

        vector.addAll(list);              // 将指定的Collection实现类对象中的元素全部添加进去
        vector.addAll(5,list);         // 将指定的Collection实现类对象中的元素全部添加到指定索引处,其他元素后移

        vector.elementAt(0);              // 获取指定索引的元素
        vector.get(0);                      // 获取指定索引的元素(仅与elementAt抛的异常有一丝差异)

        vector.setElementAt("jzx",0);     // 设置指定索引的元素
        vector.set(0,"jzx");                 // 设置指定索引的元素(返回旧值)

        Enumeration e = vector.elements();  // 获取枚举对象(Enumeration接口的匿名实现类对象)
        while(e.hasMoreElements()){
            System.out.println(e.nextElement());
        }

        String[] arr = new String[5];
        vector.copyInto(arr);        // 拷贝到指定Object对象数组(容量不足、不兼容会抛异常)(实际调用了System.arraycopy方法)
        for (Object o : arr) {
            System.out.println(o);
        }

        vector.firstElement();  // 获取第一个元素
        vector.capacity();      // 获取容量大小
        vector.trimToSize();    // 将容量压缩到实际元素个数大小

        vector.removeAllElements();  // 移除所有元素
        vector.clear();              // 移除所有元素(实际上调用了removeAllElements方法)
        vector.removeAll(list);      // 移除指定Collection实现类对象中存在的元素

        vector.removeElement("a");  // 移除指定元素(第一个)
        vector.remove("a");          // 移除指定元素(第一个) (实际上调用了removeElement方法)

        vector.removeElementAt(1);  // 移除指定索引处的元素
        vector.remove(1);           // 移除指定索引处的元素(返回旧值)

        vector.removeAll(list);          // 移除所有指定的Collection实现类对象中出现的元素
        vector.retainAll(list);          // 移除所有指定的Collection实现类对象中没有出现元素
        vector.setSize(1);             // 重新设置数组大小(null填充或舍弃后面部分元素)
        vector.isEmpty();                // 判断是否为空
        vector.contains("b");            // 判断是否包含指定元素
        vector.containsAll(list);        // 判断是否包含指定Collection实现类对象中所有出现的元素
        vector.size();                   // 返回元素个数
        vector.indexOf("a");             // 返回指定元素首次出现的索引
        vector.indexOf("a",1);       // 从指定索引开始,寻找指定元素首次出现的索引
        vector.lastIndexOf("c");        // 返回指定元素最后一次出现的索引
        vector.lastIndexOf("c",2);    // 从指定索引开始,寻找指定元素最后一次出现的索引
        List<String> subvector = vector.subList(1,2); // 截取子列表

        Object[] obj = vector.toArray();                // 转化为Object数组
        Object[] obj1 = new Object[3];
        Object[] obj2 = vector.toArray(obj1);           // 转化到指定Object数组(容量需足够),并返回一个Object数组

        Iterator<String> iterator = vector.iterator(); // 返回Iterator接口的实现类Itr对象(Vector类中的内部类,该内部类实现了Iterator接口)
        while(iterator.hasNext()){
            // vector.add("NO");                // 在迭代过程中结构性改变(增删元素),会引发ConcurrentModificationException异常
            System.out.println(iterator.next());
        }

        ListIterator<String> listIterator = vector.listIterator(); // 返回ListIterator接口的实现类ListItr对象(Vector类中的内部类,该内部类实现了Iterator接口)
        while(listIterator.hasNext()){                             // 从前往后迭代
            System.out.println(listIterator.next());
        }
        while(listIterator.hasPrevious()) {                        // 从后往前迭代,使用hasPrevious()之前必须使用hasNext()将指针指向最后
            System.out.println(listIterator.previous());
        }

        ListIterator<String> listIterator1 = vector.listIterator(1);  // 指定位置开始,返回ListIterator接口的实现类ListItr对象
        while(listIterator1.hasNext()){
            System.out.println(listIterator1.next());
        }

 

源码阅读

  Vector继承了AbstractList<E>,实现了List<E>, RandomAccess, Cloneable, java.io.Serializable接口。

构造器

     // 指定初始容量和扩容步长
   public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)  // 初始容量不能小于0
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

   // 指定初始容量(扩容步长默认为0)
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

   // 使用默认容量构造(10
    public Vector() {
        this(10);
    }

   // 使用指定Collection实现类对象构造
    public Vector(Collection<? extends E> c) {
        elementData = c.toArray();         // 转化为数组
        elementCount = elementData.length; // 获取数组长度
        if (elementData.getClass() != Object[].class) // 拷贝数组元素到elementData数组
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

 

字段

protected Object[] elementData;  // 用于存储元素

protected int elementCount;     // 元素个数

protected int capacityIncrement; // 扩容步长

private static final long serialVersionUID = -2767605614048989439L; // 序列化UID

// 一些虚拟机会在数组中保留一些标题字(header words),所以减8,防止内存溢出
// 数组最大容量(2^31-8)
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

 

常用方法

    // 将容量压缩到实际元素个数大小
    public synchronized void trimToSize() {
        modCount++;  // 修改次数加1(父类AbstractList提供)
        int oldCapacity = elementData.length;
        if (elementCount < oldCapacity) {
            elementData = Arrays.copyOf(elementData, elementCount);
        }
    }

  // 扩容
    private void grow(int minCapacity) {        
        int oldCapacity = elementData.length;  // 旧容量
      // 步长未指定,即为0时:新容量=旧容量+旧容量(2倍扩容)
      // 步长指定时,新容量=旧容量+步长
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)  // 使新容量不小于指定最小容量
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0) // 使新容量不大于最大容量值(2^31-8)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

  // 从指定索引寻找指定元素的索引
    public synchronized int indexOf(Object o, int index) { 
        if (o == null) {                              // null值单独搜索(用==判断)
            for (int i = index ; i < elementCount ; i++)
                if (elementData[i]==null)
                    return i;
        } else {                                     // 其他用equals判断
            for (int i = index ; i < elementCount ; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

  // 移除指定位置的元素
    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;  // 置null
    }

  // 指定索引插入元素
    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++;
    }

  // 移除指定索引的元素
    public synchronized boolean removeElement(Object obj) {
        modCount++;
        int i = indexOf(obj);  // 先找到指定元素的索引
        if (i >= 0) {
            removeElementAt(i); // 在移除该索引的元素
            return true;
        }
        return false;
    }

 

 

Stack

  继承了Vector线程安全,本质上利用线性表实现了栈的前进后出。

源码:

public class Stack<E> extends Vector<E> {

    public Stack() {
    }

    public E push(E item) {    // 调用了addElement,也是同步方法
        addElement(item);

        return item;
    }

    public synchronized E pop() {
        E       obj;
        int     len = size();

        obj = peek();
        removeElementAt(len - 1);

        return obj;
    }

    public synchronized E peek() {
        int     len = size();

        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }

    public boolean empty() {
        return size() == 0;
    }

  // 栈从底到顶:a b b c,search("b"),返回2
    public synchronized int search(Object o) { // 搜索指定元素到栈顶的距离
        int i = lastIndexOf(o);                // 寻找到最接近栈顶的那个元素索引

        if (i >= 0) {
            return size() - i;     // 返回距离栈顶的距离
        }
        return -1;
    }

    private static final long serialVersionUID = 1224463164541339165L;  // 序列化UID

}

 

posted @ 2020-05-07 21:25  Jiazhongxin  阅读(176)  评论(0编辑  收藏  举报