失忆ArrayList源码阅读笔记

大丈夫顶天立地,岂能郁郁久居人下

源码如下

一、ArrayList的构造器

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
    private static final long serialVersionUID = 8683452581122892189L;
    // 默认容量为10
    private static final int DEFAULT_CAPACITY = 10;
    private static final Object[] EMPTY_ELEMENTDATA = new Object[0];
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new Object[0];
    transient Object[] elementData;
    private int size;
    private static final int MAX_ARRAY_SIZE = 2147483639;

	/**
	* 调用者指定容量大小
	*/
    public ArrayList(int var1) {
    	// 大于0 传多少则设置相应的值
        if (var1 > 0) {
            this.elementData = new Object[var1];
        } else {
        	// 小于0时抛出异常
            if (var1 != 0) {
                throw new IllegalArgumentException("Illegal Capacity: " + var1);
            }
            // 等于0则设置初始容量为10
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
    /**
    * 无参构造方法
    */
    public ArrayList() {
    	// 默认创建一个容量为0的空数组
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    /**
    * 接收一个Collection
    */
	public ArrayList(Collection<? extends E> var1) {
        this.elementData = var1.toArray();
        if ((this.size = this.elementData.length) != 0) {
            if (this.elementData.getClass() != Object[].class) {
                this.elementData = Arrays.copyOf(this.elementData, this.size, Object[].class);
            }
        } else {
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
    /**
    * 删除动态增长多余的空间,通过Arrays.copyof截取
    */
    public void trimToSize() {
        ++this.modCount;
        if (this.size < this.elementData.length) {
            this.elementData = this.size == 0 ? EMPTY_ELEMENTDATA : Arrays.copyOf(this.elementData, this.size);
        }
    }
}

二、ArrayList的扩容机制

  • 扩容,所以我们找到add方法的源码
public boolean add(E var1) {
	  this.ensureCapacityInternal(this.size + 1);
	  this.elementData[this.size++] = var1;
	  return true;
}
  • add方法第一行调用了ensureCapacityInternal方法
private void ensureCapacityInternal(int var1) {
        this.ensureExplicitCapacity(calculateCapacity(this.elementData, var1));
}
// var1等于size+1,如果当前数组对象为空,则初始化容量为10,否则取当前容量
private static int calculateCapacity(Object[] var0, int var1) {
 	return var0 == DEFAULTCAPACITY_EMPTY_ELEMENTDATA ? Math.max(10, var1) : var1;
}
默认构造方法创建的ArrayList,创建时初始化为一个空数组,第一次添加元素的时候初始化容量为10
  • 获取到容量后调用ensureExplicitCapacity方法
private void ensureExplicitCapacity(int var1) {
        ++this.modCount;
        // 判断是否扩容
        if (var1 - this.elementData.length > 0) {
            this.grow(var1);
        }
    }

private void grow(int var1) {
	   int var2 = this.elementData.length;
	   // 扩容为原来的1.5倍
	   int var3 = var2 + (var2 >> 1);
	   // 如果扩容后还小于最小容量,则最小容量为新容量
	   if (var3 - var1 < 0) {
	       var3 = var1;
	   }
	   // 判断是否大于Integer的最大值
	   if (var3 - 2147483639 > 0) {
	   		// 如果var3小于0则抛出oom异常,大于最大值新容量为2147483639,否则2147483639
	       var3 = hugeCapacity(var1);
	   }
	   this.elementData = Arrays.copyOf(this.elementData, var3);
}
  • Arrays.copyof内部调用了System.arraycopy
public static <T, U> T[] copyOf(U[] var0, int var1, Class<? extends T[]> var2) {
        Object[] var3 = var2 == Object[].class ? (Object[])(new Object[var1]) : (Object[])((Object[])Array.newInstance(var2.getComponentType(), var1));
        System.arraycopy(var0, 0, var3, 0, Math.min(var0.length, var1));
        return var3;
}

未完

你可能感兴趣的:(失忆ArrayList源码阅读笔记)