Java ArrayList 内部源码实现

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







你可能感兴趣的:(Java ArrayList 内部源码实现)