1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
 // 无参构造
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 初始化为空数组
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

// 默认数组容量
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;

//
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;

// ArrayList 中的 add
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
// 确保在添加元素时,底层数组够用
ensureCapacityInternal(size + 1); // Increments modCount!!
// 将元素添加到数组末尾
elementData[size++] = e;
return true;
}

// 确保 ArrayList 能够容纳指定数量的元素
private void ensureCapacityInternal(int minCapacity) {
// 根据 minCapacity 调整数组的容量。如果容量不足,则会进行扩容
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

// 根据当前 elementData 数组的状态来决定容量

private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 如果数组是空,返回默认值 10,否则返回最小容量 minCapacity
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 1.底层数组未扩容,插入元素后未满,返回默认长度10
// 2.底层数组未扩容,插入元素后满,返回数组长度 + 1
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 不是默认数组意味着发生扩容,直接返回
// 3.底层数组发生扩容,不管满没满,都 + 1
return minCapacity;
}

//
private void ensureExplicitCapacity(int minCapacity) {
// 用于跟踪集合结构的修改次数,实现快速失败机制, 如 Iterator 遍历集合
modCount++;

// overflow-conscious code
if (minCapacity - elementData.length > 0)
// 扩容机制
grow(minCapacity);
}
// 最大容量,-8 是因为要给对象头占用内存留出空间 ,避免内存溢出
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/

private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 增长 1.5 倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果容量不足,直接设为 minCapacity
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);
}
// 在容量请求过大时,确保不会分配超出 JVM 允许范围的内存
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

  1. 在调用add方法的时候,首先调用ensureCapacityInternal()方法保证数组容量够用;
  • ensureCapacityInternal()中调用ensureCapacityInternal()方法,而ensureCapacityInternal()方法依赖于calculateCapacity()方法返回值

  • 在calculateCapacity(elementData, minCapacity)中,要判断Object[] elementData是不是默认数组,且要比较最小容量minCapacity和默认值DEFAULT_CAPACITY的值进行返回最大的那个即:

    • 是默认数组,且DEFAULT_CAPACITY >= minCapacity,返回 DEFAULT_CAPACITY

    • 是默认数组,且DEFAULT_CAPACITY < minCapacity,返回minCapacity。

    • 不是默认数组 直接返回 minCapacity

  • ensureExplicitCapacity(int minCapacity)方法,接受calculateCapacity()方法返回的值,然后进行判断是否进行扩容 minCapacity - elementData.length > 0,即:本来的size 执行 + 1 后的长度如果大于 当前数组的长度了就会执行grow() 扩容机制。

    • grow() 中,首先让 elementData.length 扩容1.5 倍,

      • 如果扩容后仍然 newCapacity - minCapacity < 0,容量不够,那直接设置容量为minCapacity ,

      • 如果扩容后,newCapacity - MAX_ARRAY_SIZE > 0,超过最大容量值,执行hugeCapacity()方法确保不会分配超出 JVM 允许范围的内存,抛出异常且进行判断 (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE,返回 Integer.MAX_VALUE 或者 MAX_ARRAY_SIZE

      • 进行Arrays.copyOf(elementData, newCapacity),扩容

  1. 将元素插入到数组末尾。

  2. 返回添加成功