ArrayList源码学习

一.继承的类
AbstractList
二.实现的类
List, RandomAccess(随机访问), Cloneable(实现clone 能被克隆), java.io.Serializable(可以序列化)

三.成员变量

private static final int DEFAULT_CAPACITY = 10; //默认容量大小10
private static final Object[] EMPTY_ELEMENTDATA = {};//定义一个不可变的空元素数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//空数组对象,用于计算添加第一个元素时要膨胀多少
transient Object[] elementData;//不被序列化的动态数组
private int size;//数组中实际元素的个数

四.构造函数

// 默认构造函数
public ArrayList()

// capacity是ArrayList的默认容量大小。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半。
public ArrayList(int initialCapacity)

// 创建一个包含collection的ArrayList
public ArrayList(Collection<? extends E> c)

五.常用方法
1.trimToSize(将elementData的数组设置为ArrayList实际的容量,动态增长的多余容量被删除了)

 public void trimToSize() {
        modCount++;
        if (size < elementData.length) {
            elementData = (size == 0)
              ? EMPTY_ELEMENTDATA
              : Arrays.copyOf(elementData, size);
        }
    }

2.grow(容量要保证能装下minCapacity所指定的容量大小)

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//将数组容量增加其容量的一半
        if (newCapacity - minCapacity < 0) //如果新的容量小于minCapacity则将容量变为minCapacity
            newCapacity = minCapacity; 
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

3.indexOf(Object o)(返回对象在数组第一次出现的位置,从前往后查)

public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

4.lastIndexOf(Object o)(返回对象在数组第一次出现的位置,从后往前查)

public int lastIndexOf(Object o) {
        if (o == null) {
            for (int i = size-1; i >= 0; i--)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = size-1; i >= 0; i--)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

5、get(int index)(根据下标查询数组中元素)

    public E get(int index) {
        rangeCheck(index); //检查下标是否超出数组大小

        return elementData(index);
    }

6、set(int index, E element)(将element替换给数组中的index位置元素,并返回被替换的元素)

public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);//将数组index位置的元素取出
        elementData[index] = element; //将element赋值给数组index位置中
        return oldValue;//返回数组原index位置的元素
    }

7、add(E e)(添加元素到数组中)

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 判断数组实际元素个数+1后是否超出数组容量,是则增加容量
        elementData[size++] = e;
        return true;
    }

8、add(int index, E element)(添加某元素到数组指定位置,如果该位置存在元素,则将该位置后面元素往后移)

public void add(int index, E element) {
        rangeCheckForAdd(index); //检查index是否超出数组实际元素个数

        ensureCapacityInternal(size + 1);  // 判断数组实际元素个数+1后是否超出数组容量,是则增加容量
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index); //将elementData数组里从索引为index的元素开始, 复制到数组elementData里的索引为index + 1的位置, 复制的元素个数为size - index个
        elementData[index] = element;
        size++;
    }
private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

9、E remove(int index)()(将数组的index位置元素移除,并返回被移除的元素)

public E remove(int index) {
        rangeCheck(index); // //检查下标是否超出数组实际元素个数

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved); //将数组index+1位置之后的元素赋值到index位置上,即数组index后面元素往前移一位,覆盖index位置元素
        elementData[--size] = null; // 将最后一位元素置空

        return oldValue;
    }

10、remove(Object o)(移除数组中指定元素)

public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++) //通过循环数组元素,找到指定元素所在的数组位置
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);//将数组index+1位置之后的元素赋值到index位置上,即数组index后面元素往前移一位,覆盖index位置元素
        elementData[--size] = null; 
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值