我们先来看看retainAll的源码
public boolean retainAll(Collection<?> c) {
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
//获得当前对象的所有元素
final Object[] elementData = this.elementData;
//w:交集中元素个数
int r = 0, w = 0;
//设置标记位
boolean modified = false;
try {
//遍历集合A
for (; r < size; r++)
//判断集合B中是否存在当前元素
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;
}
A.retainAll(B)
可以看到这个方法改变了集合A中的元素,将存在于集合A中但不存在于集合B中的元素移除。
如果集合A的大小发生了改变,返回true,即使两个集合完全没有交集,也会返回true。
如果集合A的大小没有发生改变,返回false,即使两个集合完全相同,也会返回false。
测试数据:
public class RetainAllDemo {
public static void main(String[] args){
int[] arr1={1,2,3,4};
int[] arr2={1,2,3,5};
int[] arr3={5,6,7,8};
int[] arr4={1,2,3,4};
initList(arr1, arr2, arr3, arr4);
}
private static void initList(int[] arr1, int[] arr2, int[] arr3, int[] arr4) {
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
ArrayList<Integer> list3 = new ArrayList<Integer>();
ArrayList<Integer> list4 = new ArrayList<Integer>();
//测试数据 每个数组只有四个元素 不会越界
for(int i=0; i < 4; i++){
list1.add(arr1[i]);
list2.add(arr2[i]);
list3.add(arr3[i]);
list4.add(arr4[i]);
}
//输出
System.out.println(list2.retainAll(list1));
System.out.println(list3.retainAll(list1));
System.out.println(list4.retainAll(list1));
}
}
输出结果:
所以,retainAll的返回值并不能用于判断两个集合是否存在交集,只能用于判断集合大小是否发生改变;
应该通过集合的大小判断两个集合是否有交集。
以上。
To be continued...