Java 容器源码分析之 ArrayList(5)
 
- UID
- 1066743
|

Java 容器源码分析之 ArrayList(5)
下面再看看如何做到从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
| /**
* Removes from this list all of its elements that are contained in the
* specified collection.
*/
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
/**
* Retains only the elements in this list that are contained in the
* specified collection. In other words, removes from this list all
* of its elements that are not contained in the specified collection.
*/
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++)
//1) 移除c中元素,complement == false
// 若elementData[r]不在c中,则保留
//2)保留c中元素,complement == true
// 若elementData[r]在c中,则保留
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
// 1)r == size, 则操作成功了
// 2)r != size, c.contains抛出了异常,
// 可能是因为元素和c中元素类型不兼容,或者c不支持null元素
// 则将后面尚未检查的元素向前复制
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 = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
| 我们可以看到,核心的方法在于batchRemove(Collection<?> c, boolean complement),无论是移除给定容器中的元素removeAll(Collection<?> c)还是只保留指定容器中的元素retainAll(Collection<?> c)都是通过该方法来实现的。该方法通过传入的一个布尔类型确定ArrayList中每个元素是否应该保留,详细的注释参见上面代码中的中文注释。 |
|
|
|
|
|