• 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
    
    }
  • 相关阅读:
    XMLhttp.status返回值及xmlhttp.readState值
    移动端meta设置
    css自定义checkbox样式
    base.css(css基础样式)
    css文本块中首行文本的缩进,字间距
    jq里的 ajax( ) 方法
    小程序 背景图在开发工具上显示,但是在真机调试时无效
    小程序登陆锁-登录逻辑
    背景图尺寸(background-size)
    动态渲染style 背景图片
  • 原文地址:https://www.cnblogs.com/jiazhongxin/p/12845738.html
Copyright © 2020-2023  润新知