• ArrayList源码解析


    1.无参构造方法

        //默认初始长度
        private static final int DEFAULT_CAPACITY = 10;
    
        //初始空数组
        private static final Object[] EMPTY_ELEMENTDATA = {};
    
    
        //共享空数组 和 EMPTY_ELEMENTDATA 区分用来查看扩容多少
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
        //list存储数据的数组
        transient Object[] elementData;
    
       //list长度
        private int size;
    
    
      public ArrayList() {
        //无参构造直接将 初始空数组 赋值给 存值数组
           this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
      }

    2.有参构造

    public ArrayList(int initialCapacity) {
            if (initialCapacity > 0) {
                //设置的长度大于0,就根据输入的长度创建一个数组给 存值数组
                this.elementData = new Object[initialCapacity];
            } else if (initialCapacity == 0) {
               //传入的长度等于0将 共享空数组给 存值数组
                this.elementData = EMPTY_ELEMENTDATA;
            } else {
            //传入负数抛出异常
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);
            }
        }    

    3.add方法

    /**
     * e 传入的参数
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
     /**
      * minCapacity 当前数组长度+1
      */
     private void ensureCapacityInternal(int minCapacity) {
           ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
     }
    
    /**
     *elementData 存值数组
     *minCapacity 当前数组长度+1
     */
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        //判断 存值数组 是 空数组的话
         if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
              //放入初始容量 和 当前数组长度+1 值进行对比 返回数大的
          return Math.max(DEFAULT_CAPACITY, minCapacity);
          }
          //当 存值数组 不为空的话 返回 当前数组长度+1的值
          return minCapacity;
    }
    
    /**
     *minCapacity 返回的最大长度
     */
    private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            //返回的最大长度 减去存值数组长度 大于0的话 标识需要扩容
            if (minCapacity - elementData.length > 0)
                //调用扩容方法
                grow(minCapacity);
        }
    
    /**
     *minCapacity 需要扩容的长度
     */
     private void grow(int minCapacity) {
            // 将当前数组长度给 oldCapacity
            int oldCapacity = elementData.length;
            //当前将数组长度转为二进制 并向右移动一位 转为16进制 加上原来的长度 得到新的长度
         //例如:第一次扩容的时候长度是 10 十进制转为二进制 1010 向右移动一位是 101 二进制转为10进制 为5 用5加上原来的长度10 等于15
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //新长度 减去 需要扩容的长度 小于0
            if (newCapacity - minCapacity < 0)
                //将需要扩容的长度给新长度
                newCapacity = minCapacity;
         //判断新长度是否大于最大长度 最大长度为 int的最大长度-8 int的最大长度为 2正128
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            //将 存值数组 和 扩容长度放入 复制出一个新的数组给 存值数组
            elementData = Arrays.copyOf(elementData, newCapacity);
        }

    4.get方法

    public E get(int index) {
            rangeCheck(index);
            return elementData(index);
    }
    
    //判断下标是否大于等于数组长度,是的话抛出数组越界
    private void rangeCheck(int index) {
            if (index >= size)
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    5.set方法

    public E set(int index, E element) {
        //判断下标是否越界
        rangeCheck(index);
    
        E oldValue = elementData(index);
        //将新的给下标
        elementData[index] = element;
        //返回旧的值 
      return oldValue;
    }
    
    private void rangeCheck(int index) {
        if (index >= size)
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    //获取对应下标的值
    E elementData(int index) {
        return (E) elementData[index];
    }

    6.remove方法

    public E remove(int index) {
    //判断下标是否越界 rangeCheck(index); modCount
    ++;
    //获取原来下标的值 E oldValue
    = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; } private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }

     E elementData(int index) {
    return (E) elementData[index];
    }
     
  • 相关阅读:
    结对开发第一阶段,10天冲刺第十天
    结对开发第一阶段,10天冲刺第九天
    vim 编辑器
    用户、群组和权限
    硬盘分区、格式化及文件系统管理
    系统监控
    Linux 系统初始化和服务
    文件合并与打包
    计算机原理
    Linux 之添加系统环境变量
  • 原文地址:https://www.cnblogs.com/HQ0422/p/16141555.html
Copyright © 2020-2023  润新知