ArrayList源码

ArrayList
  • 本质是数组
  • 初始容量DEFAULT_CAPACITY = 10
  • get , set操作比较有效率,是直接根据索引来操作
  • add,remove操作涉及到index时,需要对数组拷贝,消耗大

代码块

成员变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 默认数组容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 有参构造器初始容纳数组
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 无参构造器初始容纳数组
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* 存放数据的缓冲区
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* 容纳数据数
*/
private int size;

构造器:

三种构造方式:无参数,int参数,Collection参数

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
/**
* 无参构造器,默认以初始容量DEFAULT_CAPACITY = 10 构造
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 参数为int的构造器
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) { //initialCapacity参数大于0,直接构建对象
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {//initialCapacity参数等于0,用EMPTY_ELEMENTDATA
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/**
* 参数为Collection的构造器
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();//将Collection参数转数组
if ((size = elementData.length) != 0) {//Collection参数中存在数据时(非空Collection)
// 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;
}
}

辅助方法:

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
/**
* 增加Array容量
*/
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)// 要求的容量大于此时数组容量,触发grow()
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
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//当前数组容量
int newCapacity = oldCapacity + (oldCapacity >> 1);//新数组容量(右移一位代表除2^1位,新容量是旧容量的1.5倍)
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);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow ????为什么会出现小于0情况
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? //要求的容量大于最大容量时用Integer.MAX_VALUE尝试 ,否则用MAX_ARRAY_SIZE(也就是不可以按1.5倍来扩容了,数组实在太大)
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

常用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
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
/**
* 正序返回index
*/
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;
}
/**
* 倒序返回index
*/
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;
}
/**
* 根据index获取数据元素,对数组直接操作,比较高效
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
/**
* 根据index放入数据元素,对数组直接操作,比较高效
*/
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
/**
* 不要求index次序的添加,对数组直接操作,也比较高效
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
* 要求index次序的添加,需要拷贝数组,比较耗费资源
*/
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;//index后的元素数目
if (numMoved > 0)//index后存在元素(也就是被移除的这个元素不是最后一个)
System.arraycopy(elementData, index+1, elementData, index, numMoved);//index后存在元素(也就是被移除的这个元素不是最后一个)将index后的元素复制过来
elementData[--size] = null; // (最后一个数组位置将其变成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;
}
/**
* 与public remove(int index)方法差不多,只不过没有返回值
*/
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
}
/**
* 清除所有元素
*/
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
/**
* 将Collection添加进ArrayList中,需要拷贝数组,比较耗费资源
*/
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;
}
/**
* 根据index来添加Collection,需要拷贝数组,比较耗费资源
*/
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;
}

三种循环效率

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
public class testArrayList {
public static void main(String[] args) {
List list = new ArrayList();
for (int i = 0; i <10000 ; i++) {
list.add(i);
}
testArrayList.iterateByForEach(list);
testArrayList.iterateByiterator(list);
testArrayList.iterateByRandomAccess(list);
}
private static void iterateByRandomAccess (List list) {
long startTime;
long endTime;
startTime = System.currentTimeMillis();
for (int i = 0; i <list.size() ; i++) {
list.get(i);
}
endTime = System.currentTimeMillis();
System.out.println("iterateByRandomAccess Time is :" + (endTime - startTime));
}
private static void iterateByForEach (List list) {
long startTime;
long endTime;
startTime = System.currentTimeMillis();
for (Object obj : list) {
}
endTime = System.currentTimeMillis();
System.out.println("iterateByForEach Time is :" + (endTime - startTime));
}
private static void iterateByiterator (List list) {
long startTime;
long endTime;
startTime = System.currentTimeMillis();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
iterator.next();
}
endTime = System.currentTimeMillis();
System.out.println("iterateByiterator Time is :" + (endTime - startTime));
}
}
  • 随机访问 iterateByRandomAccess 最快
  • iforEach循环 中等速度
  • 迭代器 iterateByiterator 最慢