今天看了下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了。。。真的挺简单。。