java ArrayList中removeAll和retainAll都调用的batchRemove方法
removeAll方法
/**
*
* 从该列表中删除指定集合中包含的所有元素
*
* @param c 包含要从此列表中删除的元素的集合
* @return {@code true} 如果此列表因调用而更改,返回true
* @throws ClassCastException 如果此列表中某个元素的类与指定的集合不兼容,抛出类型转换异常
* (<a href="Collection.html#optional-restrictions">optional</a>)
* @throws NullPointerException 如果此列表包含空元素,并且指定的集合不允许空元素,
* 或者如果指定的集合为空,则抛出空指针异常
* @see Collection#contains(Object)
*/
public boolean removeAll(Collection<?> c) {
// 判断是否为空
Objects.requireNonNull(c);
// 移除元素,false移除传入中的元素
return batchRemove(c, false);
}
retainAll方法
/**
* 仅保留此列表中包含在指定集合中的元素。
* 换句话说,从该列表中删除指定集合中未包含的所有元素。
*
* @param c 包含要保留在此列表中的元素的集合
* @return {@code true} 如果此列表因调用而更改
* @throws ClassCastException 如果此列表中某个元素的类与指定的集合不兼容
* @throws NullPointerException 如果此列表包含空元素,并且指定的集合不允许空元素,
* 或者如果指定的集合为空,则抛出空指针异常
* @see Collection#contains(Object)
*/
public boolean retainAll(Collection<?> c) {
// 判断是否为空
Objects.requireNonNull(c);
// 移除元素,true移除传入中未包含的所有元素
return batchRemove(c, true);
}
batchRemove方法
/**
* 移除元素
* @param c 包含不要保留在此列表中的元素的集合
* @param complement true移除传入中未包含的所有元素,false移除传入中的元素
* @return
*/
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++)
// complement为true时,求并集;complement为false时,求差集
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;
}
代码精髓
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
当complement为true时,求list中与collection的并集。
当complement为false时,求list与collection的差集。