【java集合】ArrayList源码分析

ArrayList是一种基于数组实现的集合类,也是平常经常使用到的集合。其特性归纳如下:

特性
是否顺序存储顺序
是否可重复存储可以
是否可存储null可以
是否线程安全非线程安全

ArrayList的属性

首先列举一下ArrayList主要属性,方便大家理解和本文的说明:

属性说明
elementDataArrayList是基于数组实现的,这就是ArrayList用于存储
size存储元素的总数
threshold临界值,当元素数量大于thresholdthreshold,会进行扩容操作

新建一个ArrayList

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

和HashMap一样,在新建ArrzyList时可以选择是否指定容量,同样建议在可以的情况下,尽量指定一个容量,有利于提高效率。

add方法

先看一下

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

作用是添加一个元素到列表的最后面,先看一下第一行代码:

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

在容量不够的情况下,对存放元素的数组进行扩容,每次新增一个长度。因为数组的长度是固定的,所以使用 Arrays.copyOf,新建一个长度是目前1.5倍的数组,并且复制原数组的数据。

ArrayList可以在指定的索引位置,添加元素:

    public void add(int index, E element) {
        rangeCheckForAdd(index);
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

先判断指定的索引是否有越界,和add(E element)还不一样的地方是第4行,还需要对于index之后的元素都复制到index+1的位置。

get方法

get方法很简单,先判断指定的索引是否有越界,在直接返回指定索引的数据。因此ArrzyList的get方法时间复杂度是1,效率很高。

    public E get(int index) {
        rangeCheck(index);
        return elementData(index);
    }

set方法

也很简单,取出之前的元素,设置新的元素,时间复杂度也是1。

    public E set(int index, E element) {
        rangeCheck(index);
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

remove方法

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);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

也是使用了上面提高的数组复制,把index之后的所有元素,复制到index-1,相当于向前挪了一位。

总结

1.ArrayList是基于数组实现的一个集合类
2.ArrayList的get,set,add(Element,e)的效率都很高,时间复杂为O(1)
3.ArrayList的remove,add(int index, E element),时间复杂为O(n)。如果有大量的这2个的操作,可以使用LinkedList
4.ArrayList是非线程安全的

    原文作者:java集合源码分析
    原文地址: https://blog.csdn.net/gagewang1/article/details/78514192
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞