基于JDK1.8 ArrList源码分析
成员变量
1 | //序列化版本 |
构造函数
1 | public ArrayList(int initialCapacity) { |
这里用到了Arrays.copyOf()
Arrays.copyOf:public static int[] copyOf(int[] original,int newLength)
浅拷贝
1 | public static int[] copyOf(int[] original, int newLength) { |
在其内部创建了一个新的数组,然后调用arrayCopy()向其复制内容,返回出去。
添加元素
- add(E e)
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
49public boolean add(E e) {
//首先确认是否扩容,增加modCount
ensureCapacityInternal(size + 1); // Increments modCount!!
//内置数组赋值、size++
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
//如果是开始创建的空数组,minCapacity更新
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//modCount++,判断是否需要扩容
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
//如果所需的minCapacity比当前的长度长
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//扩容1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新扩容的长度还是不够
if (newCapacity - minCapacity < 0)
//将新扩容长度设为最低所需minCapacity
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
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
1 | //最大容量Integer.MAX_VALUE - 8,避免一些机器内存溢出 |
add(int index, E element)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public void add(int index, E element) {
//检查越界
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
//调用native拷贝
System.arraycopy(elementData, index, elementData, index+1,
size - index);
elementData[index] = element;
size++;
}
//如果越界,抛出异常
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}addAll(Collection<? extends E> c)
1
2
3
4
5
6
7
8public 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;
}
add总结:
- 判断是否需要扩容,将增加后的size那去判断
- 如果需要扩容,开始默认是10,每次扩容1.5,如果扩容一半不够,就用增加后的size作为扩容后的容量,需要进行数组复制来增加容量
1
elementData = Arrays.copyOf(elementData, newCapacity);
- add涉及到具体index时,需要先进行越界判断
- 最后为elementData赋值新元素,更新size
删除元素
- remove(int index)
1 | public E remove(int index) { |
- remove(Object o)
1 | public boolean remove(Object o) { |
removeAll(Collection<?> c)
1
2
3
4
5
6
7
8
9
10
11
12
13public boolean removeAll(Collection<?> c) {
//判断参数c是否为空
Objects.requireNonNull(c);
//
return batchRemove(c, false);
}
public static <T> T requireNonNull(T obj) {
if (obj == null)
//抛空指针异常
throw new NullPointerException();
return obj;
}batchRemove
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
35private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
//r就是已经遍历数组的当前下标,w就是删除后新数组的下标
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.
//contains()方法可能会抛出异常(null)
if (r != size) {
//解决办法就是将已经遍历r下标后的元素覆盖到w后
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;
}
add、remove操作都会更新modCount
改元素
1 | public E set(int index, E element) { |
查
1 | public E get(int index) { |
清空
1 | public void clear() { |
clear操作也会更新modCount
包含
1 | public boolean contains(Object o) { |
iterator
1 | private class Itr implements Iterator<E> { |
modCount继承来自AbstractList
expectedModCount判断修改标志位,Fail-fast机制