ArrayList实例及源码解析

ArrayList实例及源码解析

简介

Java.util.ArrayList类是一个动态数组类型,可以随时从链表中添加或删除一个元素。ArrayList实现了List接口并且可以动态改变大小的。当我们不知道数据元素的个数时,就可使用ArrayList;如果知道数据元素个数,就可以直接用数组。

实例

在此通过实例+分析源码来明白在舒适化ArrayList和使用其方法时底层是如何实现的

        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(-200);
        System.out.println(list.get(10));
        int i = 10;
        for (int j = 0;j <= i;j++){
            list.add(j);
        }

以上面实例对Arraylist进行剖析。

源码解读

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

首先进行arraylist初始化,此时调用arraylist的构造方法

/**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

此时构造方法会构建一个空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
使用此方法进行初始化,arraylist是一个空数组,并无长度,长度赋值实在第一次调用add()时,下面hi进行讨论。除了上述方法进行初始化外,还有一个方法可以进行初始化。

/**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    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);
        }
    }

带有容量参数构造方法进行初始化,在此不探讨

list.add(1);
/*
在第一次进行add时,此时arraylist的size是0
因为我们这里的数据类型是Integer,会先进行判断所add的这个数据是否在Integer范围之内
若所add数据在Integer范围之内,会return在缓存中的值,反正,则会创建一个Integer对象。
*/
public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
//调用add方法
public boolean add(E e) {
	ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
//确定arraylist容量
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
/*
calculateCapacity方法,两个参数,数组大小,最小所需容量0
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    	return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
    	grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        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);
}

总结:

在使用无参数构造方法进行ArraylList初始化时,此时list
容量为空,容量第一次变化是在调用add方法时进行容量初始化,默认容量大小是10,在每一次进行调用add方法时都会判断当前list容量是否满足添加数据,若容量不足以进行接下来数据的添加,则进行扩容,下一次扩容为原始容量的1.5倍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值