我们先来看看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 {//遍历集合Afor (; 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 workfor (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...