在Java中两个集合的交集可以使用 List.retainAll(Collection<?> c)
方法,其返回值为 boolean
类型,官方说明是:
/**
* Retains only the elements in this list that are contained in the
* specified collection (optional operation). In other words, removes
* from this list all of its elements that are not contained in the
* specified collection.
* */
我们不假思索的使用这个返回值进行判断集合A和集合B是否有交集。
但是注意当两个集合中的元素相同或者集合没有变化时,返回结果可能会大跌眼镜:
List<String> list1= new ArrayList<>();
List<String> list2= new ArrayList<>();
list1.add("haha");
list1.add("heihei");
list2.add("haha");
list2.add("heihei");
boolean isRetain= list1.retainAll(list2);
System.out.println(isRetain);
System.out.println(list1);
讲道理应该输出 true
,实际输出是:
I/System.out: false
I/System.out: [haha, heihei]
翻阅源码(当前使用的是JDK1.8)
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 <tt>true</tt> if this list changed as a result of the call
当两个集合中的元素相同时,使用retainAll返回的结果是false
因此不能用返回值来判断两个集合中是否有交集,作交集运算后,可以使用集合的长度是否 >0
来进行判断交集是否有。
另外,需要注意的是,如果比较的是对象集合的交集,还需要针对该对象处理equals方法和hashCode方法