碰到一个需求,文件夹1和文件夹2,各自有很多文件,要得到文件夹1中出现,但未在文件夹2出现的文件。
这个需求其实可以归到集合的操作,文件夹1作为List1,文件夹2作为List2,取List1和List2的差集,Java通过removeAll函数,可以实现,
list1.removeAll(list2);
查看ArrayList的removeAll的源码,他调用的batchRemove(),
public boolean removeAll(Collection c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
再看batchRemove的源码,如果传的第二个参数是false,保留差集,如果传的是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;
}
因此,removeAll(list2)默认调用false,将不包含的元素进行存储,实现了差集功能,
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
除此之外,List还可以实现其他的集合操作,捎带手了解下。
1. 并集(不去重)
public static void test(List list1, List list2) {
list1.addAll(list2);
System.out.println(list1);
}
看一下ArrayList的addAll()源码,做的是数组复制,
public boolean addAll(Collection c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
2. 求并集(去重)
这需要通过组合操作,例如List1和List2的并集,先将List1和List2重复的删除,然后将List2的元素都加进来,
public static void test1(List list1, List list2) {
list1.removeAll(list2);
list1.addAll(list2);
System.out.println(list1);
}
3. 求交集
public static void test2(List list1, List list2) {
list1.retainAll(list2);
System.out.println(list1);
}
我们看retainAll()的源码,他其实调用的,就是这个batchRemove()函数,但是第二个参数,给的是true,所以这两种操作,都可以实现交集,
public boolean retainAll(Collection c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
参考,
https://www.cnblogs.com/qlqwjy/p/9812919.html