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;
    }
    

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

原文地址:https://www.cnblogs.com/cwhan/p/13965926.html