文章首发于:clawhub.club


基于 JDK1.8 的ArrayList源码:

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* 版权所有(c)1997,2017,Oracle和/或其附属公司。版权所有。
* ORACLE 所有权/机密。使用须遵守许可条款。
*/

package java.util;

import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import sun.misc.SharedSecrets;

/**
* Resizable-array implementation of the <tt>List</tt> interface. Implements
* all optional list operations, and permits all elements, including
* <tt>null</tt>. In addition to implementing the <tt>List</tt> interface,
* this class provides methods to manipulate the size of the array that is
* used internally to store the list. (This class is roughly equivalent to
* <tt>Vector</tt>, except that it is unsynchronized.)
* 实现 List 接口的可变数组,实现了所有列表操作的方法,允许所有的元素,包括 null。
* 除了实现 List 接口外,ArrayList 还提供了一些方法用来控制存储列表内部的数组大小。
* (除了它不是同步的外,这个类相当于 Vector(类))
*
*
* <p>The <tt>size</tt>, <tt>isEmpty</tt>, <tt>get</tt>, <tt>set</tt>,
* <tt>iterator</tt>, and <tt>listIterator</tt> operations run in constant
* time. The <tt>add</tt> operation runs in <i>amortized constant time</i>,
* that is, adding n elements requires O(n) time. All of the other operations
* run in linear time (roughly speaking). The constant factor is low compared
* to that for the <tt>LinkedList</tt> implementation.
* size、isEmpty、get、set、iterator 和 listIterator 这些操作(方法)运行在恒定时间()。
* add 这个操作(方法),时间复杂度都是 O(n) 。
* 其他所有的操作(方法)运行在线性时间(粗略的讲)。
* 这个常数因子(10)相比于 LinkedList 实现类来说是比较低的。
*
*
* <p>Each <tt>ArrayList</tt> instance has a <i>capacity</i>. The capacity is
* the size of the array used to store the elements in the list. It is always
* at least as large as the list size. As elements are added to an ArrayList,
* its capacity grows automatically. The details of the growth policy are not
* specified beyond the fact that adding an element has constant amortized
* time cost.
* 每个 ArrayList 实例都有一个 capacity,这个 capacity 是被用来在列表中存储元素的数组大小。
* capacity 总是至少和列表的大小一样大。
* 当元素被添加到 ArrayList 中,列表的 capacity 也会自动增长。
* 除了添加一个元素有恒定均摊时间花费这个事实外,增长策略的细节没有做规定。
*
*
* <p>An application can increase the capacity of an <tt>ArrayList</tt> instance
* before adding a large number of elements using the <tt>ensureCapacity</tt>
* operation. This may reduce the amount of incremental reallocation.
* 一个程序在添加大量的元素之前可以先增加 ArrayList 实例的 capacity,
* 通过使用 ensureCapacity 方法可能会减少重新分配增量的次数。
*
*
* <p><strong>Note that this implementation is not synchronized.</strong>
* If multiple threads access an <tt>ArrayList</tt> instance concurrently,
* and at least one of the threads modifies the list structurally, it
* <i>must</i> be synchronized externally. (A structural modification is
* any operation that adds or deletes one or more elements, or explicitly
* resizes the backing array; merely setting the value of an element is not
* a structural modification.) This is typically accomplished by
* synchronizing on some object that naturally encapsulates the list.
* 注意:这个实现类(ArrayList) 不是同步的。
* 如果多个线程并发访问一个 ArrayList 实例,并且至少有一个线程在结构上修改了列表,那么这个线程必须在
* (ArrayList 的)方法外部进行同步操作。(结构上的修改是添加删除一个或多个元素,或者是显示调整后备数组的
* 大小,仅仅是设置值(使用 set 方法)不算是结构上的修改。)
* 这通常是通过在列表上自然封装的一些对象进行同步操作来完成的。
*
*
* If no such object exists, the list should be "wrapped" using the
* {@link Collections#synchronizedList Collections.synchronizedList}
* method. This is best done at creation time, to prevent accidental
* unsynchronized access to the list:<pre>
* List list = Collections.synchronizedList(new ArrayList(...));</pre>
* 如果不存在此类对象,列表应该用 Collections.synchronizedList 静态方法包装。
* 这(使用包装列表)应该在创建的时候做,为了防止非同步的访问列表(示例代码如下):
* List list = Collections.synchronizedList(new ArrayList(...));
*
*
* <p><a name="fail-fast">
* The iterators returned by this class's {@link #iterator() iterator} and
* {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:</a>
* if the list is structurally modified at any time after the iterator is
* created, in any way except through the iterator's own
* {@link ListIterator#remove() remove} or
* {@link ListIterator#add(Object) add} methods, the iterator will throw a
* {@link ConcurrentModificationException}. Thus, in the face of
* concurrent modification, the iterator fails quickly and cleanly, rather
* than risking arbitrary, non-deterministic behavior at an undetermined
* time in the future.
* 这个类(ArrayList)的 iterator() 方法和 listIterator 方法返回出来的迭代器都是 fail-fast 的。
* 如果列表在迭代器创建之后在结构上被修改,除了调用迭代器的 remove 方法和 add 方法外,迭代器都会抛出 ConcurrentModificationException 异常。
* 因此,在并发修改情况下,迭代器快速干净地出 fail,而不是在未来某个不确定的时间,冒任意和不确定的风险。
*
*
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
* as it is, generally speaking, impossible to make any hard guarantees in the
* presence of unsynchronized concurrent modification. Fail-fast iterators
* throw {@code ConcurrentModificationException} on a best-effort basis.
* Therefore, it would be wrong to write a program that depended on this
* exception for its correctness: <i>the fail-fast behavior of iterators
* should be used only to detect bugs.</i>
* 注意:迭代器的 fail-fast 行为可能不像它保证的那样,一般来说,在非同步并发修改情况下,不可能去给出
* 任何硬性的保证。
* fail-fast 的迭代器会尽最大的努力抛出 ConcurrentModificationException 异常。
* 因此,写程序依赖这个异常为了正确性这点是错误的,迭代器的 fail-fast 行为仅仅被用来检查(程序中的) bug。
*
*
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
* 这个类(ArrayList)是 Java 集合框架的一员。
*
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
* @see List
* @see LinkedList
* @see Vector
* @since 1.2
* 编写者:Josh Bloch、Neal Gafter
* 参看:Collection、List、LinkedList、Vector
* 这个类自从 Java 1.2 就有了
*/

public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
// 序列号
private static final long serialVersionUID = 8683452581122892189L;

/**
* Default initial capacity.
* 默认的初始化容量,10。
*/
private static final int DEFAULT_CAPACITY = 10;

/**
* Shared empty array instance used for empty instances.
* (初始化容量为 0或者初始化集合为空)空实例共享此空数组(私有静态不可变变量)。
*/
private static final Object[] 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.
* (没有指定初始化)默认(容量)大小(10)空实例共享此空数组(私有静态不可变变量),我们将它和 EMPTY_ELEMENTDATA 区分开来是为了知道当第一元素被添加时需要扩容多少。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
* 存储 ArrayList 元素的数组。ArrayList 的容量是这个数组的长度。
* 当添加第一个元素时,任何带有 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的空 ArrayList
* 都将扩展为 DEFAULT_CAPACITY。
*
* transient 关键字修饰,序列化时该值不会被带上
*/
transient Object[] elementData; // non-private to simplify nested class access 非私有方便内部嵌套类访问

/**
* The size of the ArrayList (the number of elements it contains).
* ArrayList 的大小(ArrayList 包含的元素数量)
*
* @serial
* 对象序列化时被带上
*/
private int size;

/**
* Constructs an empty list with the specified initial capacity.
* 使用指定初始化容量构造一个空列表
*
* @param initialCapacity the initial capacity of the list
* initialCapacity 参数为这个列表的初始化容量
* @throws IllegalArgumentException if the specified initial capacity
* is negative
* 抛出 IllegalArgumentException 异常,如果指定的初始化容量是负数
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
// 创建指定初始化容量的 Object 数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
// 使用有指定初始化值的共享空实例
this.elementData = EMPTY_ELEMENTDATA;
} else {
// 抛出 IllegalArgumentException 异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}

/**
* Constructs an empty list with an initial capacity of ten.
* 使用初始化容量 10 来构造一个空列表
*/
public ArrayList() {
// 使用无指定初始化值的共享空实例,和上面的空实例区分开
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
* 使用包含元素(元素个数可能为 0)的指定集合构造列表,并按照这个集合的迭代器返回元素顺序构造
*
* @param c the collection whose elements are to be placed into this list
* c 参数为要将它的元素放入列表的集合
* @throws NullPointerException if the specified collection is null
* 抛出 NullPointerException(空指针)异常,如果指定的集合为 null
*/
public ArrayList(Collection<? extends E> c) {
// 如果集合 c 为 null,则在调用 toArray 方法时会抛出空指针异常
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
// c.toArray 是具体的集合类中的方法,可能并不会正确的返回 Object 数组,所以这里要判断一下,
// 如果不是 Object 数组,就通过 Arrays 工具类的 copyOf 方法转换成 Object 数组
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
// 使用有指定初始化值的共享空实例
this.elementData = EMPTY_ELEMENTDATA;
}
}

/**
* Trims the capacity of this <tt>ArrayList</tt> instance to be the
* list's current size. An application can use this operation to minimize
* the storage of an <tt>ArrayList</tt> instance.
* 调整 ArrayList 实例的 capacity 为列表当前的 size。
* 程序可以使用这个方法最小化 ArrayList 实例的存储(节省不需要的空间)。
*/
public void trimToSize() {
// 修改次数加 1
modCount++;
// 在 size 小于数组的长度(数组中存在 null 引用)前提下
// 如果 size == 0 ,说明数组中都是 null 引用,就让 elementData 指向 EMPTY_ELEMENTDATA,
// 否则,就拷贝 size 长度的 elementData 数组元素,再让 elementData 指向这个数组对象
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}

/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
* 如果有需要,增加 ArrayList 实例的容量值,来确保它可以容纳至少
* 指定的最小容量(minCapacity)数量的元素。
*
* @param minCapacity the desired minimum capacity
* minCapacity 参数为列表所需的最小容量
*/
public void ensureCapacity(int minCapacity) {
// 如果 elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA(未指定初始化值的 ArrayList 实例),则 minExpand = 0
// 否则 minExpand = DEFAULT_CAPACITY(10)
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
// 如果 minCapacity > minExpand,一种情况是 minCapacity > 0,另一种情况是 minCapacity > 10
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}

// 类内私有方法,对象无法直接方法,供内部其他方法使用
// 计算列表的容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 如果 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA(未指定初始化值的 ArrayList 实例),则返回 DEFAULT_CAPACITY(10) 和 minCapacity 数值最大的一个作为列表的容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 否则(不是未指定初始化值得 ArrayList 实例),直接返回 minCapacity
return minCapacity;
}

// 类内私有方法,对象无法直接方法,供内部其他方法使用
// 确保 ArrayList 内部容量充足
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

// 类内私有方法,对象无法直接方法,供内部其他方法使用
// 确保已经有明确的容量
private void ensureExplicitCapacity(int minCapacity) {
// 修改次数加 1
modCount++;

// overflow-conscious code
// 有溢出意识的代码
// 当 minCapacity 大于 elementData 数组长度时,再调用 grow 方法。
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}

/**
* 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
* 能分配的最大数组大小,Integer.Max_VALUE - 8
* 为什么最大数组大小不是 Integer 最大值?因为一些虚拟机(VMs)在数组中会保留一些头消息,会占用一些空间
* 尝试分配比这个(规定最大)值更大的值可能会导致 OutOfMemoryError:请求的数组大小超过了虚拟机的限制
*/
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.
* 确保 ArrayList 实例可以容纳至少指定的最小容量(minCapacity)数量的元素。
*
* @param minCapacity the desired minimum capacity
* minCapacity 参数为列表所需的最小容量
*/
private void grow(int minCapacity) {
// overflow-conscious code
// 有溢出意识的代码

// oldCapacity 的值为 elementData 中数组长度值
int oldCapacity = elementData.length;
// 使用位运算提高运算速度,newCapacity 是 oldCapacity 的 1.5 倍。
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果 oldCapacity 的 1.5 倍还比 minCapacity 小,那么 newCapacity = minCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果 oldCapacity 的 1.5 倍比 MAX_ARRAY_SIZE 大,那么调用 hugeCapacity 做点事情
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);

// minCapacity is usually close to size, so this is a win:
// minCapacity 的值通常接近于 size 的值,所以这就是个胜利(节省空间)

// 最终 elementData 指向复制了 newCapacity 的新数组对象
elementData = Arrays.copyOf(elementData, newCapacity);
}

// 对于巨大的容量的做法
private static int hugeCapacity(int minCapacity) {
// 如果 minCapacity < 0 就直接抛出 OutOfMemoryError
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
// 否则如果 minCapacity > MAX_ARRAY_SIZE,返回 Integer.MAX_VALUE,或者返回 MAX_ARRAY_SIZE 值
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

/**
* Returns the number of elements in this list.
* 返回列表中元素的数量
* @return the number of elements in this list
* 返回值是列表中元素的数量
*/
public int size() {
return size;
}

/**
* Returns <tt>true</tt> if this list contains no elements.
* 如果列表中没有元素则返回 true
*
* @return <tt>true</tt> if this list contains no elements
* 返回值为列表的 size 是否等于 0
*/
public boolean isEmpty() {
return size == 0;
}

/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
* at least one element <tt>e</tt> such that
* <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
* 如果列表包含指定的元素则返回 true,
* 更正式的说是,当且仅当列表包含至少一个元素 e,
* 就像这样 return (o == null ? e == null : o.equals(e))
* 如果测试对象 o 为 null,那么这一个元素 e 指向 null,返回 true
* 否则就用 o 调用 equals 方法,判断 o 和 e 是否相等来决定返回值
*
* @param o element whose presence in this list is to be tested
* o 参数为在这个列表中被测试的元素
* @return <tt>true</tt> if this list contains the specified element
* 返回值为 o 在列表中的位置是否大于 0
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}

/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
* or -1 if there is no such index.
* 返回列表中第一次出现指定元素的索引(下标),如果列表中不存在这个(指定)元素就返回 -1
* 更正式的说是,返回最小的索引,
* 就像这样 (o == null ? get(i) == null : o.equals(get(i)))
* 或者(列表中)没有该元素的索引就返回 -1
* 这里方法注释是源码注释不规范(不是我翻译时漏了),没有参数和返回值的注释,
* 不知道是编写这个类中哪个大佬的锅,txtx
*/
public int indexOf(Object o) {
// 判断 o 是不是指向 null
if (o == null) {
// 如果 o 指向 null,正序遍历元素列表(注意这里用 size,不用 capacity),如果找到就返回索引值
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
// 如果 o 不指向 null,正序遍历元素列表,使用元素的 equals 方法判断元素值,如果找到就返回索引值
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
// 找不到返回 -1
return -1;
}

/**
* Returns the index of the last occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the highest index <tt>i</tt> such that
* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
* or -1 if there is no such index.
* 返回列表中最后一次出现指定元素的索引(下标),如果列表中不存在这个(指定)元素就返回 -1
* 更正式的说是,返回最小的索引,
* 就像这样 (o == null ? get(i) == null : o.equals(get(i)))
* 或者(列表中)没有该元素的索引就返回 -1
*/
public int lastIndexOf(Object o) {
// 判断 o 是不是指向 null
if (o == null) {
// 如果 o 指向 null,倒序遍历元素列表(注意这里用 size,不用 capacity),如果找到就返回索引值
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
// 如果 o 不指向 null,正序遍历元素列表,使用元素的 equals 方法判断元素值,如果找到就返回索引值
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
// 找不到返回 -1
return -1;
}

/**
* Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
* elements themselves are not copied.)
* 返回 ArrayList 实例的浅拷贝(元素本身没有拷贝,只是把数组中的对象引用拷贝了一遍)
*
* @return a clone of this <tt>ArrayList</tt> instance
* 返回值是 ArrayList 实例的克隆
*/
public Object clone() {
try {
// 只是复制了 ArrayList 数组对象引用(栈中),没有拷贝具体的对象(堆中)
ArrayList<?> v = (ArrayList<?>) super.clone();
// elementData 复制和 modCount 值复制
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
// 这不应该发生,因为我们已经声明了 Cloneable
throw new InternalError(e);
}
}

/**
* Returns an array containing all of the elements in this list
* in proper sequence (from first to last element).
* 以适当的顺序(从第一个到最后一个元素)返回一个包含列表中所有元素的数组
*
* <p>The returned array will be "safe" in that no references to it are
* maintained by this list. (In other words, this method must allocate
* a new array). The caller is thus free to modify the returned array.
* 这个返回的数组是安全的,列表中没有保留对数组元素值的引用(换句话说,这个方法必须分配一个新的数组)
* 调用者因此可以自由修改返回的数组(对列表中的值不会有影响,反过来,列表中的值修改也不会影响数组中的值)
*
* <p>This method acts as bridge between array-based and collection-based
* APIs.
* 这个方法充当基于数组和基于集合API的桥梁(集合与数组的转换)
*
* @return an array containing all of the elements in this list in
* proper sequence
* 返回值为以适当的顺序包含列表中所有元素的数组
*/
public Object[] toArray() {
// copyOf 方法最终调用的是 System.arraycopy 静态方法,并且是个本地方法,无法查看源代码
return Arrays.copyOf(elementData, size);
}

/**
* Returns an array containing all of the elements in this list in proper
* sequence (from first to last element); the runtime type of the returned
* array is that of the specified array. If the list fits in the
* specified array, it is returned therein. Otherwise, a new array is
* allocated with the runtime type of the specified array and the size of
* this list.
* 以适当的顺序(从第一个到最后一个元素)返回一个包含列表中所有元素的数组;
* 返回数组的运行类型是指定数组的类型。
* 如果列表适合指定的数组,则返回到指定数组中(指定数组长度和列表 size 大小相等)
* 否则一个以指定数组的类型为运行类型,大小为列表 size 的新数组将被分配
*
* <p>If the list fits in the specified array with room to spare
* (i.e., the array has more elements than the list), the element in
* the array immediately following the end of the collection is set to
* <tt>null</tt>. (This is useful in determining the length of the
* list <i>only</i> if the caller knows that the list does not contain
* any null elements.)
* 如果列表适合指定的数组并且还有剩余空间(即指定数组比列表有更多的元素),在数组中紧跟集合末尾的元素被设置为 null。(仅当调用者知道列表中不包含任何 null 元素,在决定列表长度时才是有用的)
*
* @param a the array into which the elements of the list are to
* be stored, if it is big enough; otherwise, a new array of the
* same runtime type is allocated for this purpose.
* a 参数是一个用来存储列表元素的数组,前提是这个数组足够大;否则,一个以转换目的和指定数组相同类型的数组将会被分配
* @return an array containing the elements of the list
* 返回值为包含列表元素的数组
* @throws ArrayStoreException if the runtime type of the specified array
* is not a supertype of the runtime type of every element in
* this list
* 抛出 ArrayStoreException 异常,如果指定数组的类型不是列表元素类型的超类型
* @throws NullPointerException if the specified array is null
* 抛出 NullPointerException 异常,如果指定的数组是 null
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
// 如果指定的数组长度小于 size,返回一个以列表元素填充的新数组
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
// 数组拷贝,System.arraycopy 方法为本地方法
System.arraycopy(elementData, 0, a, 0, size);
// 如果指定数组长度大于 size,超过列表 size 的部分赋值为 null
if (a.length > size)
a[size] = null;
// 再将填充后指定的数组返回
return a;
}

// Positional Access Operations
// 按位置访问操作(方法)
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}

/**
* Returns the element at the specified position in this list.
* 返回列表中的指定位置的元素
*
* @param index index of the element to return
* index 参数为要返回元素的下标
* @return the element at the specified position in this list
* 返回值为列表中指定位置的元素
* @throws IndexOutOfBoundsException {@inheritDoc}
* 抛出 IndexOutOfBoundsException 异常
*/
public E get(int index) {
// 边界检查
rangeCheck(index);

return elementData(index);
}

/**
* Replaces the element at the specified position in this list with
* the specified element.
* 用指定元素替换列表中指定位置的元素值
*
* @param index index of the element to replace
* index 参数为要替换的元素的下标
* @param element element to be stored at the specified position
* element 参数为要存储到指定位置的元素值
* @return the element previously at the specified position
* 返回值为先前指定位置的旧元素值
* @throws IndexOutOfBoundsException {@inheritDoc}
* 抛出 IndexOutOfBoundsException 异常
*/
public E set(int index, E element) {
// 边界检查
rangeCheck(index);
// 保存旧值
E oldValue = elementData(index);
// 替换成新值
elementData[index] = element;
// 返回旧值
return oldValue;
}

/**
* Appends the specified element to the end of this list.
* 添加指定元素到列表末尾
*
* @param e element to be appended to this list
* e 参数为要添加到列表的元素
* @return <tt>true</tt> (as specified by {@link Collection#add})
* 返回值为 true(当被指定为集合时)
*/
public boolean add(E e) {
// 确保在 ArrayList 实例的 size 基础上加 1,容量仍然充足,扩充是以 elementData 数组长度的 1.5 倍扩的
ensureCapacityInternal(size + 1); // Increments modCount!!
// 这里一行代码实现了两步,一步是 size 加 1,另一步是将 e 添加到 elementData 末尾
elementData[size++] = e;
return true;
}

/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
* 插入指定的值到列表指定的位置。
* 将当前位置的元素(如果有的话)和任何后续的元素向右移动(将它们的索引加 1)
*
* @param index index at which the specified element is to be inserted
* index 参数为要被插入的指定元素的索引
* @param element element to be inserted
* element 参数为要插入的元素
* @throws IndexOutOfBoundsException {@inheritDoc}
* 抛出 IndexOutOfBoundsException 异常
*/
public void add(int index, E element) {
// add 方法的边界检查
rangeCheckForAdd(index);
// 确保在 ArrayList 实例的 size 基础上加 1,容量仍然充足
ensureCapacityInternal(size + 1); // Increments modCount!!
// 元素向后移动是通过 System.arraycopy 方法实现的
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
// 数组指定位置赋值
elementData[index] = element;
// ArrayList 的 size 要加 1
size++;
}

/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
* 移除列表指定位置的元素,将后续的元素向左移动(将它们的减 1)
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
// 边界检查
rangeCheck(index);

// 修改次数加 1
modCount++;
// 保存旧值
E oldValue = elementData(index);

// 计算要移动的元素个数
int numMoved = size - index - 1;
if (numMoved > 0)
// 使用 System.arraycopy 方法实现元素向左移动
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 一行代码,两步操作,一步是将 size 减 1,另一步是将最后一个元素指向 null,让垃圾回收器清理没有引用的对象
elementData[--size] = null; // clear to let GC do its work
// 返回旧值
return oldValue;
}

/**
* Removes the first occurrence of the specified element from this list,
* if it is present. If the list does not contain the element, it is
* unchanged. More formally, removes the element with the lowest index
* <tt>i</tt> such that
* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
* (if such an element exists). Returns <tt>true</tt> if this list
* contained the specified element (or equivalently, if this list
* changed as a result of the call).
* 移除列表中第一次出现的指定元素,前提是这个元素值存在。
* 如果列表不包含这个元素,列表不会改变。
*
*
* @param o element to be removed from this list, if present
* @return <tt>true</tt> if this list contained the specified element
*/
public boolean remove(Object o) {
// 如果 o 指向 null,遍历 elementData 数组,如果找到了指定元素就删除并返回 true
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
// 否则,遍历 elementData 数组,使用 equals 方法判断相等,如果找到了指定元素就删除并返回 true
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
// 没有找到,返回 false
return false;
}

/*
* Private remove method that skips bounds checking and does not
* return the value removed.
* 私有的删除方法,跳过了边界检查并且不返回删除的值
*/
private void fastRemove(int index) {
// 修改次数加 1
modCount++;
// 计算要移动的元素的个数
int numMoved = size - index - 1;
if (numMoved > 0)
// 使用 System.arraycopy 方法实现元素向左移动
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 一行代码,两步操作,一步是将 size 减 1,另一步是将最后一个元素指向 null,让垃圾回收器清理没有引用的对象
elementData[--size] = null; // clear to let GC do its work
}

/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
* 移除列表中的所有元素,列表将会在调用返回后置为空
*/
public void clear() {
// 修改次数加 1
modCount++;

// clear to let GC do its work
// elementData 数组中的引用都置为 null,让垃圾回收器清除没有引用的对象
for (int i = 0; i < size; i++)
elementData[i] = null;

size = 0;
}