• Vector源码解读


    1.背景

    阅读源码是提高编程技能的有效方式...

    面试中也经常问到源码相关的问题.....

    2.源码解读

    在解读Vector时大家可以先解读ArrayList,因为这个两个的逻辑几乎是一样的....

    ArrayList源码解读:https://www.cnblogs.com/newAndHui/p/16101626.html

    区别在于

    1.Vector的很多方法都是同步的即线程安全的,二ArrayList的很多方法时线程非同步的;

    2.Vector扩容默认是原来的1倍,二ArrayList默认是按照原来的1.5倍扩容;

    3.Vectory对象创建时默认数组长度为10,而ArrayList对象创建时是一个空数组,在添加第一个元素是才设置数组长度为10

    阅读源码前自己写一个与Vector功能差不多的对象MyVector,相信你看懂了MyVector,那么Vector你就自然懂了...

    package com.ldp.collection.my;
    
    import java.util.AbstractList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.RandomAccess;
    
    /**
     * @author 姿势帝-博客园
     * @address https://www.cnblogs.com/newAndHui/
     * @WeChat 851298348
     * @create 04/05 10:51
     * @description
     */
    public class MyVector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
        private static final long serialVersionUID = -2767605614048989439L;
        protected Object[] elementData; // 存放元素的数组对象
        protected int elementCount; // 存放的元素个数
        protected int capacityIncrement; // 数组扩容时的扩容量,默认为0,表示安装原来的1倍扩容,10扩容一次后为20
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 数组的最大容量
    
        /**
         * 无参数构造方法,默认容量为10
         */
        public MyVector() {
            this(10);
        }
    
        /**
         * 自定义容量的构造方法
         */
        public MyVector(int initialCapacity) {
            this(initialCapacity, 0);
        }
    
        /**
         * 自定义容量 和 扩容数的构造方法
         *
         * @param initialCapacity   数组长度
         * @param capacityIncrement 扩容时的增加长度,默认为0,安装原来的1倍扩容
         */
        public MyVector(int initialCapacity, int capacityIncrement) {
            super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: " +
                        initialCapacity);
            this.elementData = new Object[initialCapacity];
            this.capacityIncrement = capacityIncrement;
        }
    
        /**
         * 线程安全的,所以很多操作方法都是加了 synchronized 关键字的
         */
        @Override
        public synchronized boolean add(E e) {
            // 累加修改次数
            modCount++;
            // 确定容量
            ensureCapacityHelper(elementCount + 1);
            // 在原来的元素后面加一个元素
            elementData[elementCount++] = e;
            return true;
        }
    
        private void ensureCapacityHelper(int minCapacity) {
            // 当最小需要的容量大于数组长度时进行扩容
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        private void grow(int minCapacity) {
            // 原来的容量
            int oldCapacity = elementData.length;
            // 新的容量,capacityIncrement=0时,newCapacity=oldCapacity+oldCapacity,即按照原来的1倍扩容
            int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
            // 加一倍后长度还是不够,则用传递过来的数值minCapacity(addAll来说,就是原长度+新集合长度)
            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) // overflow
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ?
                    Integer.MAX_VALUE :
                    MAX_ARRAY_SIZE;
        }
    
        @Override
        public synchronized E get(int index) {
            if (index >= elementCount)
                throw new ArrayIndexOutOfBoundsException(index);
    
            return elementData(index);
        }
    
        @SuppressWarnings("unchecked")
        E elementData(int index) {
            return (E) elementData[index];
        }
    
        @Override
        public synchronized int size() {
            return elementCount;
        }
    }

    完美!

  • 相关阅读:
    如何在宿主机上查看kvm虚拟机的IP
    virt-viewer 连kvm 虚机
    用virsh console vhosts 卡住
    sshpass 实现shell脚本直接加载密登录服务器
    maven创建helloword项目
    linux 安装maven
    xz -d Python-3.4.7.tar.xz
    查看哪个用户登录过服务器 记录 时间 和 ip
    两台linux服务器各有两个不同的用户 其中一个服务器可以无密码登录服务器
    maven私服nexus
  • 原文地址:https://www.cnblogs.com/newAndHui/p/16101869.html
Copyright © 2020-2023  润新知