您的位置:首页 > 编程语言 > Java开发

Java ArrayList 内部源码实现

2016-04-27 21:47 585 查看
今天看了下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;
}


下面来看看最常用的几个方法 add get remove
@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了。。。真的挺简单。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: