ArrayList源码学习(1)

作者: 心扬 | 来源:发表于2017-10-27 09:38 被阅读19次

    数据结构定义

    从数据结构的角度来说,ArrayList是线性表基于java的顺序表示和实现,数据结构中定义其是一组地址连续的存储单元,所以其内部其实是数组

    我们可以在顺序表中随意的获取指定位置的数据,即遍历读取非常方便,在其末尾追加元素也非常方便,而且可以根据需要增长或缩短其长度。

    当然我们也可以在指定位置插入元素,但是通常不建议这样使用

    插入元素

    如图所示:在n+1长度的数组中,在i处插入一个元素,我们要将i后面的所有元素全部向后移动,如果在移动之前我们检测,现有数组中的元素已满,则先需要扩展数组,然后在进行移动,最后在i处插入元素,所以其性能并不高!

    接下来一点一滴的学习ArrayList,其中的泛型全部用Integer类型

    • 属性
    /**
      * ArrayList初始容量
      */
    private static final int DEFAULT_CAPACITY = 10;
    
    private static final Object[] EMPTY_ELEMENTDATA = {};
    
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    //容器中真正用于存储数据的数组
    transient Object[] elementData; 
    // 容器中元素的个数
    private int size;
    
    • 构造方法学习

    ArrayList有三个构造方法

    ArrayList() 
    ArrayList(int initialCapacity) 
    ArrayList(Collection<? extends E> c)
    

    1.无形参的构造方法使用

    ArrayList<Integer> list = new ArrayList<Integer>();
    

    源码解析

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    

    当使用无形参的构造方法初始化ArrayList对象时,将静态属性DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给缓存数组

    2.指定初始容量的构造方法使用

    ArrayList<Integer> list = new ArrayList<Integer>(5);
    

    源码解析

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);
        }
    }
    

    形参initialCapacity为容器的初始容量,当前初始容量initialCapacity大于0时,创建一个长度为初始容量initialCapacity的Object数组,赋值给缓存数组elementData,如果初始容量为0,则将静态属性EMPTY_ELEMENTDATA赋值给缓存数组,初始容量小于0时,抛出异常

    3.以其他容器作为参数的构造方法

    public ArrayList(Collection<? extends E> c) {
        //将参数中的容器转换为数组,赋值给elementData
        elementData = c.toArray();
        //在判断条件中将elementData的长度赋值给size,修改当前ArrayList的长度
        if ((size = elementData.length) != 0) {
            //转换后,elementData中有元素,当元素的类型不适Object类型时,将其中的元素全部拷贝到长度为size的Object数组中,并将最后结果赋值给elementData
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            //形参转换为数组后,数组中没有元素,则将EMPTY_ELEMENTDATA赋值给elementData,使得elementData仍然是一个空的Object数组
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
    

    相关文章

      网友评论

        本文标题:ArrayList源码学习(1)

        本文链接:https://www.haomeiwen.com/subject/kugaextx.html