天天看点

一步一步解析集合框架ArrayList源码(2)

我在阅读源码的过程中很多时候是没有头绪的。所以为了避免大家也遇到这种状况,源码不求全求大,做到“透过实践看源码”,分块分层。

首先对ArrayList做个总体介绍:

ArrayList的底层存储结构是数组,实际上在这个类中真正保存数据的是内部定义的一个数组,自身的数据操作只是封装了数组的操作!
           
  • 修改集合元素
public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<String>();
        list.add("first");
        list.add("second");
        String ele1=list.get();
        System.out.println(ele1);
        list.set(,"第一个");
        System.out.println(list.get());
    }
           

输出结果: first

第一个

源码分析:

/**
     * 替换,设置;
     * 将索引index的元素值设置为element
     * 返回原索引的元素值
     */
    public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
           
  • 删除集合元素
public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<String>();
        list.add("first");
        list.add("second");
        System.out.println(list.remove());
        System.out.println(list.get());
    }
           

输出结果:

second
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: , Size: 
           

说明删除成功,已经不存在”second”的元素值。

源码分析:

/**
     *通过索引删除元素,返回删除的元素值
     */
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        //删除前的索引元素值
        E oldValue = elementData(index);
        //计算要复制的长度,即从index+1至最后一个元素共计多少
        int numMoved = size - index - ;
        if (numMoved > )
       /**
        * 第一个参数:原数组,
        * 第二个参数:复制开始索引,
        * 第三个参数:目标数组,
        * 第四个参数:目标数组复制开始索引,
        * 第五个参数:复制长度
        */
             System.arraycopy(elementData, index+, elementData, index, numMoved);
        //清空最后一个元素值
        elementData[--size] = null; 

        return oldValue;
    }
           
/**
     *根据元素值进行删除
     */
    public boolean remove(Object o) {
        //遍历数组elementData,比较进行删除
        if (o == null) {
            for (int index = ; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = ; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

    /*
     * 私有方法;
     * 删除索引index元素值
     */
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - ;
        if (numMoved > )
            System.arraycopy(elementData, index+, elementData, index,
                             numMoved);
        elementData[--size] = null; 
    }
           

继续阅读