Java集合系列[2]-ArrayList分析与源码解析

概述

之前介绍了 Collection 的整体架构。本文将通过Collection的具体类来加深理解。首先我们来看List,而ArrayList是List中最常用的,所以我们从他下手。主要分为以下部分:

  • 第一部分 简介
  • 第二部分 数据结构分析
  • 第三部分 源码分析
  • 第四部分 遍历方式
  • 第五部分 toArray()异常

ArrayList简介

ArrayList的定义如下:

1
2
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArrayList是一个数组列表,相当于动态数组。与Java中的数组相比,它的容量能够动态增长。它继承于AbstractList,实现了List、RandomAccess、Cloneable、java.io.Serializable这几个接口。

ArrayList继承了AbstractList,实现了List接口。它是一个数组列表,提供了相关的添加、修改、删除、遍历等功能。

ArrayList实现了RandomAccess接口,即提供了随机访问的功能。RandomAccess是Java中用来被List实现,为List提供快速访问功能的。除了各种List外,StackVector也实现了RandomAccess接口,这其实也说明了Stack和Vector也是List。在ArrayList中,我们可以通过索引来快速地访问元素,这就是快速随机访问,也可以通过迭代器来访问,稍后我们会比较通过”快速随机访问“和“迭代器访问”的效率。

ArrayList实现了Cloneable,这就表明ArrayList覆盖了clone()方法,可以被克隆。

ArrayList实现了java.io.Serializable,这就表明ArrayList支持被序列化,可以通过序列化被传输。

Vector不同,ArrayList访问不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中使用Vector或者CopyOnWriteArrayList

ArrayList的构造方法

1
2
3
public ArrayList(); //构造一个空数组列表,容量为10
public ArrayList(int initialCapacity);//构造一个空数组列表,容量为指定大小。DEFAULT_CAPACITY是ArrayList的默认容量,当由于增加数据而导致容量不足的时候,容量会增加为上次容量的1.5倍。
public ArrayList(Collection<? extends E> c); // 构建一个包含c集合的数组列表。

ArrayList的API

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
public int size(); // 获取当前数组列表元素的个数;
public boolean isEmpty(); // 判断当前数组列表是否为空;
public boolean contains(Object o); // 判断当前数组列表是否至少有一个o对象;
public Object[] toArray(); // 返回一个包含数组列表所有元素的数组,并保持了相应的顺序;
public <T> T[] toArray(T[] a); // 返回一个包含数组列表所有元素的数组,并保持了相应的顺序;此外返回的元素类型转化为运行时类型T,下面会详细说这个;
public boolean add(E e); // 在数组列表的尾部附加上指定元素;
public boolean remove(Object o); // 删除在数组列表最小处的该元素;
public void clear(); // 清空当前数组列表的所有元素(设置为null),执行后size=0;
public boolean addAll(Collection<? extends E> c); // 根据迭代器顺序,把指定集合添加到当前数组列表尾部;
public boolean removeAll(Collection<?> c); // 在当前数组列表中删除元素,这些元素都包含指定集合中;
public boolean retainAll(Collection<?> c); // 仅保留在指定集合中的元素,删除不在指定集合中的元素;
public Iterator<E> iterator(); // 返回迭代器,不支持向前迭代
public void forEach(Consumer<? super E> action)
public Spliterator<E> spliterator()
public boolean removeIf(Predicate<? super E> filter)
public void replaceAll(UnaryOperator<E> operator)
/* AbstractList新增的接口 */
public E get(int index); // 返回指定索引处的元素;
public E set(int index, E element); // 替换指定索引处的元素;
public void add(int index, E element); // 在指定索引处替换为指定元素,指定索引处的原来元素及后面元素依次往后推;
public E remove(int index); // 删除指定索引处的元素,后面的元素往前推;
public boolean addAll(int index, Collection<? extends E> c)// 根据迭代器顺序,把指定集合添加到当前数组列表尾部,原索引处元素及后面元素依次往后推;
public ListIterator<E> listIterator(int index); // 在指定索引处返回列表迭代器,当该迭代器第一次执行next()的时候返回该索引处元素,执行previous()返回该索引处的前一个元素;
public ListIterator<E> listIterator(); // 返回列表迭代器;
public List<E> subList(int fromIndex, int toIndex); // 返回一个包含fromIndex,不包含toIndex的子列表;如果fromIndex=toIndex,返回空列表;子列表的修改也会影响原数组列表;
public void sort(Comparator<? super E> c)
/* ArrayList新增的接口 */
public Object clone(); // 返回数组列表的一个浅克隆(a shallow copy);
public void ensureCapacity(int minCapacity); // 增加ArrayList对象的容量,使其容量不低于minCapacity;
public void trimToSize(); //整理ArrayList对象的容量为它当前的size,去掉预留元素位置,内存紧张的时候会用到。

数据结构分析

ArrayList的继承关系

1
2
3
4
5
6
7
8
9
10
11
12
13
java.lang.Object
|
v
java.util.AbstractCollection
|
v
java.util.AbstractList
|
v
java.util.ArrayList
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArrayList与Collection的关系

2016-09-03_ArrayList与Collection的关系.png

ArrayList包含2个重要数据:elementDatasize

  • elementData 是”Object[]类型的数组”,它是ArrayList实际存储元素的地方。实际上,elementData是一个动态数组,默认的容量是10,我们可以通过ArrayList(int initialCapacity)来设定它的容量(不小于10)。容量的大小会根据数组列表的长度增长而增长,具体的增长可以查看ensureCapacity()方法。
  • size 是动态数组的实际大小。

ArrayList源码分析(基于JDK 1.8.0_40)

源码分析

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
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
package java.util;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* 序列化版本号
*/
private static final long serialVersionUID = 8683452581122892189L;
/**
* 默认初始化容量大小.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 空实例共享的空数组实例
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 空实例共享的空数组实例
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 保存ArrayList数据的数组
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* ArrayList实际数据的数量
*/
private int size;
/**
* 指定ArrayList容量大小的构造器
*/
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);
}
}
/**
* 构造一个空ArrayList,默认容量为其实是0,当第一次调用add()的时候,该数组大小会被扩展到10(DEFAULT_CAPACITY)
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 用指定集合来构造一个ArrayList,ArrayList的顺序是集合的迭代器的迭代顺序
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
/**
* 整理ArrayList对象的容量设置为它当前的size,去掉预留元素位置,内存紧张的时候会用到。
*/
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
/**
* 增加ArrayList对象的容量,确保容量不低于minCapacity;
* 如果ArrayList当前容量不足以容纳当前的全部元素,设置 新的容量=旧的容量*1.5
*/
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity) {
// 如果当前列表的数组是空数组,那么最小容量就选minCapacity和默认容量的较大值
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
// 修改次数+1
modCount++;
// 如果最小容量大于数组的实际大小,则增长数组容量
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 数组可以分配的最大的大小。有些虚拟机在一个数组中保留了头部信息,尝试去分配最大的数
* 组大小可能会导致OutOfMemoryError错误:请求的数组大小超过了虚拟机的限制。
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 增加数组容量,确保ArrayList可以容纳至少minCapacity个元素
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 新容量 = 旧容量 + (旧容量 / 2)
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果新容量小于期望最小容量,那么新容量重新修改为期望最小容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 重新设置新容量后,把数组元素重新构造为含全部元素的新容量数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**
* ArrayList可分配的最大的大小
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 返回ArrayList的实际大小
*/
public int size() {
return size;
}
/**
* 判断当前ArrayList是否为空
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 判断当前ArrayList是否包含指定元素
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* 正向查找,返回指定元素在ArrayList中最小索引,如果指定元素不在当前ArrayList中则返回-1
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* 反向查找,返回指定元素的ArrayList中的最大索引,如果指定元素不存在于当前ArrayList中则返回-1
*/
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* 返回当前ArrayList的一个浅复制实例,浅复制ArrayList实例的元素和当前ArrayList实例的元素是对应的, 如果一个地方修改,另一个地方也会相应变化
*/
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
/**
* 返回一个数组,包含了当前ArrayList的全部元素(依次从头部到尾部)
*/
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
/**
* 返回一个包含数组列表所有元素的数组,并保持了相应的顺序;此外返回的元素类型转化为运行时类型T
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
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(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
// 位置访问操作
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
/**
* 返回当前ArrayList中指定索引处的元素
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
/**
* 替换当前ArrayList中指定索引处的元素
*/
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
/**
* 在ArrayList的尾部附加上指定的元素
*/
public boolean add(E e) {
// 确认容量是否足够
ensureCapacityInternal(size + 1); // Increments modCount!!
// 把当前ArrayList的末尾设置为当前值
elementData[size++] = e;
return true;
}
/**
* 在指定索引处替换为指定元素,指定索引处的原来元素及后面元素依次往后推;
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
/**
* 删除指定索引处的元素,后面的元素往前推;
*/
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
/**
* 删除在数组列表最小处的该元素;
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
/*
* 私有的移除方法,跳过了边界检查,不会返回删除的值
*/
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
/**
* 清空当前数组列表的所有元素(设置为null),执行后size=0;
*/
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
/**
* 根据迭代器顺序,把指定集合添加到当前数组列表尾部;
*/
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
/**
* 根据迭代器顺序,把指定集合添加到当前数组列表尾部,原索引处元素及后面元素依次往后推;
*/
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
/**
* 删除[fromIndex,toIndex)中所有的元素,后面的元素往前推
*/
protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null;
}
size = newSize;
}
/**
* 检查指定索引是否在当前ArrayList的范围中,如果不在则抛出一个运行时异常;该方法不会检查指定索引是否是负数
*/
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 给add和addAll使用的另一个版本的rangeCheck
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 构造一个IndexOutOfBoundsException的异常消息
*/
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
/**
* 在当前数组列表中删除元素,这些元素都包含指定集合中;
*/
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
/**
* 仅保留在指定集合中的元素,删除不在指定集合中的元素;
*/
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
/**
* 批量删除
*/
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
/**
* 保存当前ArrayList实例到一个流中
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
//先写入容量
s.writeInt(size);
// 再依次写入每个元素
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
* 从一个流中重新设定当前的ArrayList实例
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
// Read in size, and any hidden stuff
s.defaultReadObject();
// 先读取容量
s.readInt(); // ignored
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
Object[] a = elementData;
// 再一次读取每个元素
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
/**
* 在指定索引处返回列表迭代器,当该迭代器第一次执行next()的时候返回该索引处元素,执行previous()返回该索引处的前一个元素;
*/
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
/**
* 返回列表迭代器;
*/
public ListIterator<E> listIterator() {
return new ListItr(0);
}
/**
* 返回迭代器,不支持向前迭代
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* 一个AbstractList.Itr的优化版本
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
/**
* 一个AbstractList.ListItr的优化版本
*/
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
/**
* 返回一个包含fromIndex,不包含toIndex的子列表;如果fromIndex=toIndex,返回空列表;子列表的修改也会影响原数组列表;
*/
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
public int size() {
checkForComodification();
return this.size;
}
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
}
public boolean addAll(Collection<? extends E> c) {
return addAll(this.size, c);
}
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
parent.addAll(parentOffset + index, c);
this.modCount = parent.modCount;
this.size += cSize;
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
public ListIterator<E> listIterator(final int index) {
checkForComodification();
rangeCheckForAdd(index);
final int offset = this.offset;
return new ListIterator<E>() {
int cursor = index;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;
public boolean hasNext() {
return cursor != SubList.this.size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
public boolean hasPrevious() {
return cursor != 0;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = SubList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[offset + (i++)]);
}
// update once at end of iteration to reduce heap write traffic
lastRet = cursor = i;
checkForComodification();
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
throw new ConcurrentModificationException();
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+this.size;
}
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
public Spliterator<E> spliterator() {
checkForComodification();
return new ArrayListSpliterator<E>(ArrayList.this, offset,
offset + this.size, this.modCount);
}
}
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
* 生成一个支持late-binding和fail-fast的分割迭代器
*/
@Override
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
static final class ArrayListSpliterator<E> implements Spliterator<E> {
private final ArrayList<E> list;
private int index; // current index, modified on advance/split
private int fence; // -1 until used; then one past last index
private int expectedModCount; // initialized when fence set
/** Create new spliterator covering the given range */
ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
int expectedModCount) {
this.list = list; // OK if null unless traversed
this.index = origin;
this.fence = fence;
this.expectedModCount = expectedModCount;
}
private int getFence() { // initialize fence to size on first use
int hi; // (a specialized variant appears in method forEach)
ArrayList<E> lst;
if ((hi = fence) < 0) {
if ((lst = list) == null)
hi = fence = 0;
else {
expectedModCount = lst.modCount;
hi = fence = lst.size;
}
}
return hi;
}
public ArrayListSpliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null : // divide range in half unless too small
new ArrayListSpliterator<E>(list, lo, index = mid,
expectedModCount);
}
public boolean tryAdvance(Consumer<? super E> action) {
if (action == null)
throw new NullPointerException();
int hi = getFence(), i = index;
if (i < hi) {
index = i + 1;
@SuppressWarnings("unchecked") E e = (E)list.elementData[i];
action.accept(e);
if (list.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
return false;
}
public void forEachRemaining(Consumer<? super E> action) {
int i, hi, mc; // hoist accesses and checks from loop
ArrayList<E> lst; Object[] a;
if (action == null)
throw new NullPointerException();
if ((lst = list) != null && (a = lst.elementData) != null) {
if ((hi = fence) < 0) {
mc = lst.modCount;
hi = lst.size;
}
else
mc = expectedModCount;
if ((i = index) >= 0 && (index = hi) <= a.length) {
for (; i < hi; ++i) {
@SuppressWarnings("unchecked") E e = (E) a[i];
action.accept(e);
}
if (lst.modCount == mc)
return;
}
}
throw new ConcurrentModificationException();
}
public long estimateSize() {
return (long) (getFence() - index);
}
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}
@Override
public boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
// figure out which elements are to be removed
// any exception thrown from the filter predicate at this stage
// will leave the collection unmodified
int removeCount = 0;
final BitSet removeSet = new BitSet(size);
final int expectedModCount = modCount;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
@SuppressWarnings("unchecked")
final E element = (E) elementData[i];
if (filter.test(element)) {
removeSet.set(i);
removeCount++;
}
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
// shift surviving elements left over the spaces left by removed elements
final boolean anyToRemove = removeCount > 0;
if (anyToRemove) {
final int newSize = size - removeCount;
for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
i = removeSet.nextClearBit(i);
elementData[j] = elementData[i];
}
for (int k=newSize; k < size; k++) {
elementData[k] = null; // Let gc do its work
}
this.size = newSize;
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
return anyToRemove;
}
@Override
@SuppressWarnings("unchecked")
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final int expectedModCount = modCount;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
elementData[i] = operator.apply((E) elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
Arrays.sort((E[]) elementData, 0, size, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
}

总结

  • ArrayList实际是通过一个数组去保存元素的;如果使用默认的构造器,则ArrayList的默认容量是10
  • 当ArrayList容量不足以容纳全部元素的时候,会重新扩容:新的容量 = 原始容量 + (原始容量 / 2)(JDK1.6版本是:新的容量 = (原始容量 * 3) / 2 + 1)。
  • ArrayList的克隆函数,即是将所有全部元素克隆到一个数组中。
  • ArrayList实现java.io.Serializable的方式。当写入到输出流的时候,先写入容量,再一次写入每个元素;当读取输入流的时候,先读取容量,再依次读取每个元素。

ArrayList的遍历

第一种:通过迭代器遍历

1
2
3
4
5
Integer value = null;
Iterator iter = list.iterator();
while (iter.hasNext()) {
value = iter.next();
}

第二种:随机访问,通过索引值遍历

1
2
3
4
5
Integer value = null;
int size = list.size();
for (int i = 0; i < size; i++) {
value = list.get(i);
}

第三种:通过forEach遍历

1
2
3
4
Integer value = null;
for (Integer integ:list) {
value = integ;
}

下面通过实例来测试这3种遍历方式的耗时:

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
package com.archerda;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* ArrayList遍历方式和效率的测试程序。
*/
public class ArrayListTest {
public static void main(String[] args) {
Integer size = 100000;
List<Integer> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
list.add(i);
}
randomAccessToTraverse(list);
iteratorToTraverse(list);
foreachToTraverse(list);
}
public static void randomAccessToTraverse(List list) {
long startTime;
long endTime;
startTime = System.currentTimeMillis();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println("randomAccessToTraverse:" + interval + " ms");
}
public static void iteratorToTraverse(List list) {
long startTime;
long endTime;
startTime = System.currentTimeMillis();
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
iter.next();
}
endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println("iteratorToTraverse:" + interval + " ms");
}
public static void foreachToTraverse(List list) {
long startTime;
long endTime;
startTime = System.currentTimeMillis();
for (Object obj : list)
;
endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println("foreachToTraverse:" + interval + " ms");
}
}

执行结果:

1
2
3
randomAccessToTraverse:5 ms
iteratorToTraverse:9 ms
foreachToTraverse:6 ms

结论:
遍历ArrayList的时候,效率的排序依次是:随机访问遍历 > forEach遍历 > 迭代器遍历


toArray()异常

Arraylist有2个toArray()方法:

1
2
public Object[] toArray();
public <T> T[] toArray(T[] a);

调用toArray()的时候,可能会抛出ClassCastException异常,例如下面这种情况:

1
Integer[] integers2 = (Integer[]) list.toArray();

这个时候就会抛出:

1
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;

因为toArray()返回的是Object[],而Java 不支持向下转型,把Object[]转换为Integer[]就会出现异常。但是Object[]里面每个单独的Object是可以强转成Integer的,因为Object指向的实际类型就是Integer,所以强转没有问题。而Object[]本身就只是Object类型的数组,强转成Integer[]就会出错。

可以用toArray(T[] a)改进,方式如下:

1
Integer[] integers = arraylist.toArray(new Integer[arraylist.size()]);


参考文档