java1.8 arraylist源码_Java 1.8 ArrayList 源码分析

我们声明一个初始容量为1的ArrayList。看看在add时候到底发生了什么。

public class Main {

public static void main(String[] args) {

final ArrayList objects = new ArrayList<>(1);

objects.add("A");

objects.add("B");

objects.add("C");

}

}

当声明的容量小于10时的情况

执行第一个语句objects.add("A"),此时size是0,执行ensureCapacityInternal(1)。

private static final int DEFAULT_CAPACITY = 10;

private static final Object[] EMPTY_ELEMENTDATA = {};

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

public boolean add(E e) {

ensureCapacityInternal(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

calculateCapacity(elementData,1),此时数组为空,所以return 10。调用ensureExplicitCapacity(10)。

private void ensureCapacityInternal(int minCapacity) {

ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

}

private static int calculateCapacity(Object[] elementData, int minCapacity) {

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

return Math.max(DEFAULT_CAPACITY, minCapacity);

}

return minCapacity;

}

10 > 0 调用grow(10)

private void ensureExplicitCapacity(int minCapacity) {

modCount++;

// overflow-conscious code

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

newCapacity - minCapacity = -10 < 0 ,所以newCapacity=10。elementData = Arrays.copyOf(elementData,10); elementData容量变为了10。

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);

}

无需扩容的情况

接下来执行objects.add("B")。此时size是1,执行ensureCapacityInternal(2)。

public boolean add(E e) {

ensureCapacityInternal(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

calculateCapacity(elementData,2),此时数组不为空,所以return 2。调用ensureExplicitCapacity(2)。

private void ensureCapacityInternal(int minCapacity) {

ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

}

private static int calculateCapacity(Object[] elementData, int minCapacity) {

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

return Math.max(DEFAULT_CAPACITY, minCapacity);

}

return minCapacity;

}

2-10 < 0 所以不需要grow,直接执行上面的elementData[size++] = e。

private void ensureExplicitCapacity(int minCapacity) {

modCount++;

// overflow-conscious code

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

正常扩容情况

1.5倍扩容,将原来的数组整个拷贝过去。

int newCapacity = oldCapacity + (oldCapacity >> 1);

elementData = Arrays.copyOf(elementData, newCapacity)

总结

当我们new一个ArrayList的时候,初始容量为0,内部表示为一个空数组。在一次add后,容量为扩充为10。

我们可以自定义初始容量的大小,值得注意的是,如果定义的容量小于10,在第一次add后,容量会扩充为10。

容量不够时,按照1.5倍原容量大小扩容,复制原容量数组的所有元素到新容量的数组去。所以说扩容是一个比较昂贵的操作。我们可以根据需求设置初始容量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值