我们知道在Java中求两个集合的交集可以使用List 的retainAll方法
List<String> strList1 = new ArrayList<>();
List<String> strList2 = new ArrayList<>();
strList1.add("1");
strList1.add("2");
strList2.add("1");
boolean result = strList1.retainAll(strList2);
System.out.println(result);
System.out.println(strList1);
输出结果
true
[1]
但是注意当两个集合中的元素相同时,返回结果可能会和你想的不一样
List<String> strList1 = new ArrayList<>();
List<String> strList2 = new ArrayList<>();
strList1.add("1");
strList1.add("2");
strList2.add("1");
strList2.add("2");
boolean result = strList1.retainAll(strList2);
System.out.println(result);
System.out.println(strList1);
预期结果
true
[1,2]
实际输出结果
false
[1, 2]
可以发现交集是正确结果,但是返回值居然是false
。
当两个集合中的元素相同时,使用retainAll
返回的结果是false
因此不能用返回值来判断两个集合中是否有交集
以下是JDK1.8中的ArrayList的retainAll方法的源码
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++)
//循环判断list2中是否包括list1中的元素,将相等的元素放到list1的数组中
//其中w就是相等元素的个数,elementData中0至w都是相等的元素
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
//只有相等元素的数量和源集合的数量不一致才能进到这个if中,modified 才会为true
if (w != size) {
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
当然查看这个方法的javadoc
@return {@code true} if this list changed as a result of the call
只有list因为调用被修改的话,才会返回true