ArrayList源码解析

       ArrayList和HashMap、LinkedList一样,是常用的数据结构。ArrayList提供了一个动态数组,弥补了数组的长度固定,增加元素操作消耗大的不足。但因为ArrayList存储了对象数组,构造对象也造成了性能开销,所以相对布言,如果数组的长度可知,使用数组的效率最高,反之则可使用ArrayList。

 ArrayList内部使用Object[]存储数据

    private transient Object[] elementData;

 ArrayList使用Obect数组elementData来存储数据,这样可以存储任意类型的数据。

 构造函数

    public ArrayList() {
	this(10);
    }

 默认构造函数的数组的容量为10。

 ArrayList添加元素

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

 添加元素时,元素添加到ArrayList容器的尾部。

 在添加元素之前,先判断数组的容量是否需要扩容ensureCapacity(size+1),传的参数是当前数组的size+1。

确保ArrayList容器容量

    public void ensureCapacity(int minCapacity) {
	modCount++;
	int oldCapacity = elementData.length;
	if (minCapacity > oldCapacity) {
	    Object oldData[] = elementData;
	    int newCapacity = (oldCapacity * 3)/2 + 1;
    	    if (newCapacity < minCapacity)
		newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
	}
    }

 在ensureCapacity方法中,先把参数(新索引值)minCapacity与数组容器的原长度oldCapacity做比较,如果参数minCapacity大于原长度,就说明数组已经饱和,需要进行扩容。

扩容的具体实现是把原来的长度增加50%再增加1,然后,把旧数组的数据拷贝到新数组里(使用System.arrayCopy()实现)。

在指定位置(index)添加元素

    public void add(int index, E element) {
	if (index > size || index < 0)
	    throw new IndexOutOfBoundsException(
		"Index: "+index+", Size: "+size);

	ensureCapacity(size+1);  // Increments modCount!!
	System.arraycopy(elementData, index, elementData, index + 1,
			 size - index);
	elementData[index] = element;
	size++;
    }

 实现流程也是先判断数组需不需要扩容,然后把从index往后面的数组元素,向后移动一位。再把index位置的数组元素的引用赋予要插入的元素。

查找指定位置(index)的元素

    public E get(int index) {
	RangeCheck(index);

	return (E) elementData[index];
    }

 查找元素的方法比较简单,先是查看索引index值是否越界,如果在范围之内,直接返回数组的该索引元素。

从数组的指定位置index删除元素

    public E remove(int index) {
	RangeCheck(index);

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

	int numMoved = size - index - 1;
	if (numMoved > 0)
	    System.arraycopy(elementData, index+1, elementData, index,
			     numMoved);
	elementData[--size] = null; // Let gc do its work

	return oldValue;
    }

 在ArrayList中删除指定位置的元素时,如果这个index不是数组的最大下标位置,就把index之后的所有元素向前移动一位,来填充index位置的元素移除后的空白。

总结:

        ArrayList是一个动态数组数据结构,可以灵活地添加元素,查找性能好,而在指定位置添加和删除元素时性能下降,因为要移动数组的数据。所以ArrayList适用于查找多,而在数组内指定位置操作少的场景。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值