今天看了下Arraylist 的源码 原本以为内部会比较复杂 但是没想到内部源码很简单。。。 在这里简要记录下吧 相信只要看过源码 就能看懂。。
继承和实现了以下接口和类
public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess
成员变量 只有3个
private static final int MIN_CAPACITY_INCREMENT = 12; //最小的增长容量
int size; //当前集合的元素数量 transient Object[] array; //真正存放数据的数组
public ArrayList(int capacity) { //参数是容量的意思 if (capacity < 0) { throw new IllegalArgumentException("capacity < 0: " + capacity); } array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]); } public ArrayList() { array = EmptyArray.OBJECT; } public ArrayList(Collection<? extends E> collection) { if (collection == null) { throw new NullPointerException("collection == null"); } Object[] a = collection.toArray(); if (a.getClass() != Object[].class) { Object[] newArray = new Object[a.length]; System.arraycopy(a, 0, newArray, 0, a.length); a = newArray; } array = a; size = a.length; }
@Override public boolean add(E object) { Object[] a = array; int s = size; if (s == a.length) { //如果元素的数量达到了数组a的长度 说明需要扩充数组大小了 利用MIN_CAPACITY_INCREMENT扩充
Object[] newArray = new Object[s + (s < (MIN_CAPACITY_INCREMENT / 2) ? MIN_CAPACITY_INCREMENT : s >> 1)]; System.arraycopy(a, 0, newArray, 0, s); //这个函数是最主要的 整个ArrayList 这个而函数使用最多 是个jni函数 array = a = newArray; //扩充后重新赋值 } a[s] = object; //赋值元素 size = s + 1; //大小加1 modCount++; //修改次数增加 return true; }
@Override public void add(int index, E object) { //插入相应位置 Object[] a = array; int s = size; if (index > s || index < 0) { //越界了 throwIndexOutOfBoundsException(index, s); } if (s < a.length) { //可直接插入的情况 把 index位置及其后面的元素向后移动一个位置 System.arraycopy(a, index, a, index + 1, s - index); } else { //需要扩容了 // assert s == a.length; Object[] newArray = new Object[newCapacity(s)]; //计算扩容大小 然后扩容 System.arraycopy(a, 0, newArray, 0, index); //index前面的放入扩容后的数组 System.arraycopy(a, index, newArray, index + 1, s - index); //index后面的放入扩容后的数组 array = a = newArray; } a[index] = object; //把要插入的值 插入 size = s + 1; modCount++; }
@SuppressWarnings("unchecked") @Override public E get(int index) { //太简单 。。。 if (index >= size) { throwIndexOutOfBoundsException(index, size); } return (E) array[index]; }
@Override public E remove(int index) { //也很简单。。 Object[] a = array; int s = size; if (index >= s) { throwIndexOutOfBoundsException(index, s); } @SuppressWarnings("unchecked") E result = (E) a[index]; System.arraycopy(a, index + 1, a, index, --s - index); a[s] = null; // Prevent memory leak size = s; modCount++; return result; }
public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length);
第一个参数是 资源对象 第二个参数是要复制的开始位置 第三个参数是目标对象 第四个参数是目标对象开始的位置 最后一个是 要复制的长度
也就是 把src中的从srcPos位置开始 复制 length哥元素到 dst的dstPos位置到 dstPos+length-1位置
这就ok了。。。真的挺简单。。