转载请注明出处:http://blog.csdn.net/u012250875/article/details/78203365
1.如何求差集
Collection系列的集合求差集十分简单,仅仅调用Collection中提供的removeAll方法即可。
A-B(A差B)求法:A.removeAll(B),A-B的结果存放在A中
2.removeAll方法解读
2.1关于removeAll的返回值
求A-B时,由于结果最后存放在集合A中,如果集合A的元素与求差集之前比发生变化,返回值为true,否则为false
2.2 removeAll和retainAll
removeAll和retainAll的具体定义如下:
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c)
二者定义一致,入参相同,返回值意义相同,都表示集合元素是否发生变化。惊人的相似啊。我们如果看一看Collection的实现类,如ArrayList的源码,会发现removeAll和retainAll两个方法的实现都几乎一致,唯独调用batchRemove方法时第二参数一个是false,一个是true,观察batchRemove方法,发现该方法根据第二个参数,如果为true则记录B集合有的且A集合有的元素,即为交集;如果为false则记录A集合中有而B集合中没有的元素,即为A-B;而返回值对应的变量modified,该值在w != size(w为结果集的个数,size为A集合元素个数)时才会为true。源码如下:
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
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++)
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;
}
3. 封装方法
有时候求差集,并不想破坏原有的集合,并且可能是想用一个list和一个set进行求差集,虽然工具方法返回值是个List,但是List转Set还是很方便,构造方法即可。实现如下
/**
* @author puyf
* @Description:求集合a-b
* @param a
* @param b
* @return 返回A-B的结果
*/
public static <T,K extends Collection<? extends T>> List<T> sub(K a,K b){
List<T> result = new ArrayList<>();
if(a!=null){
result = new ArrayList<>(a);
result.removeAll(b);
}
return result;
}
使用如下:
public static void main(String[] args) {
List<Number> list1 = new ArrayList<>(Arrays.asList(new Integer[]{5,6,7}));
Set<Integer> set = new HashSet<>(Arrays.asList(new Integer[]{5,6}));
System.out.println("{5,6,7}差{5,6}的结果为"+sub(list1,set));
}
//结果
{5,6,7}差{5,6}的结果为[7]
更多集合工具类,集合操作(点击查看)