zoukankan      html  css  js  c++  java
  • ArrayList源码分析

    ArrayList源码分析

    一只java小白

    最近学到集合,于是想分析一下ArrayList的源码。

    • 默认长度是多少?

      通过翻阅源码,发现是10

      //默认长度是10  
      private static final int DEFAULT_CAPACITY = 10;
      //无参数构造器,这里只初始化了一个数组(ArrayList通过数组来存储数据)。
      public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
      }
      //找到源码,发现是一个空的数组,那么长度是咋变成10的呢?
      private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
      
    • 我此时发现了一句注释:

      * Any empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
      * will be expanded to DEFAULT_CAPACITY when the first element is added.
      

      所以该数组的长度是在添加第一个数据时变成10的!!!下面来做个假设,于是我跟踪add()方法

     public boolean add(E e) {
         modCount++;
         //参数解释:
         //    e:形参,elementData:存放的数据,size:此时存放多个数据(默认是0)
         
         add(e, elementData, size);
         return true;
     }
    //继续跟踪,发现是在这个if语句中进行了扩容
     private void add(E e, Object[] elementData, int s) {
        //数组长度也是0,条件为true
         if (s == elementData.length)
             elementData = grow();
         elementData[s] = e;
         size = s + 1;
     }
    
    private Object[] grow() {
        //实参变为1
        return grow(size + 1);
    }
    private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        //先不分析,这是创建ArrayList对象时指定长度或者第一次扩容之后再次扩容,才进到这里
    	//
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //扩容为之前的1.5倍取整
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                                                      minCapacity - oldCapacity, /* minimum growth */
                                                      oldCapacity >> 1           /* preferred growth */);
            // public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
            // assert oldLength >= 0
            // assert minGrowth > 0
    
            //   int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
            // if (newLength - MAX_ARRAY_LENGTH <= 0) {
            //   return newLength;
            // }
            //	return hugeLength(oldLength, minGrowth);
            //}
            //赋值给新创建出的数组,旧的数组自动回收!!!
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            
            //跳到这里,都明白了,在10和size中取最大值,进行第一次扩容
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }
    
    
    • Arrays.copyOf方法深究

      //静态泛型方法
      public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
          @SuppressWarnings("unchecked")
          //判断newType是否是Object数组
          T[] copy = ((Object)newType == (Object)Object[].class)
              ? (T[]) new Object[newLength]
              : (T[]) Array.newInstance(newType.getComponentType(), newLength);
          
          //重点,复制数组
          //原数组:original,目标数组:copy
         //从original下标0开始将数据复制到copy数组中,第一个数据放在下标0中,长度为 Math.min(original.length, newLength)
          System.arraycopy(original, 0, copy, 0,
                           Math.min(original.length, newLength));
          return copy;
      }
      

    有必要总结下泛型:),继续努力!!!

  • 相关阅读:
    CSP-S2019 括号树
    [CQOI2007]余数求和
    CF1000E We Need More Bosses
    [HAOI2009]毛毛虫
    ls命令
    HTML的标签 属性 等等
    虚拟机安装Tools
    1.1 什么是安全渗透
    004-Kali Linux安装-熟悉环境
    003-Kali Linux 安装-持久加密USB安装、熟悉环境、熟悉BASH命令
  • 原文地址:https://www.cnblogs.com/cwhan/p/13965926.html
Copyright © 2011-2022 走看看