前提須要明白List是引用類型,引用類型採用引用傳遞。數組
咱們常常會遇到一些需求求集合的交集、差集、並集。例以下面兩個集合:ui
List<String> list1 = new ArrayList<String>(); list1.add("A"); list1.add("B"); List<String> list2 = new ArrayList<String>(); list2.add("B"); list2.add("C");
0.求差集
例如,求List1中有的可是List2中沒有的元素:this
public static void test3(List list1, List list2) { list1.removeAll(list2); System.out.println(list1); }
結果:spa
[A]code
查看ArrayList的removeAll的源碼blog
public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false); }
再查看batchRemove的源碼:(若是傳的第二個參數是false,保留差集;若是傳的是true,保留的是交集)ci
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; }
是從新定義elementData數組的元素,下面代碼的做用是將本集合中不包含另外一個集合的元素從新加入元素,以此實現刪除的功能(注意上面調用的方法傳的參數是false,也就是不包含的元素得以保留,實現差集的功能)element
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];rem
1.求並集(不去重)---將一個集合所有加入另外一個集合
public static void test(List list1, List list2) { list1.addAll(list2); System.out.println(list1); }
結果:源碼
[A, B, B, C]
查看ArayList的addAll()源碼是數組複製:
public boolean addAll(Collection<? extends E> 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; }
再查看System的arraycopy發現是一個native方法(本地方法):---其實system類的好多方法都是native方法
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
2.求並集(去重)
例如:求List1和List2的並集,並實現去重。
思路是:先將list中與list2重複的去掉,以後將list2的元素所有添加進去。
public static void test1(List list1, List list2) { list1.removeAll(list2); list1.addAll(list2); System.out.println(list1); }
結果:
[A, B, C]
3.求交集
例如:求List1和List2中都有的元素。
public static void test2(List list1, List list2) { list1.retainAll(list2); System.out.println(list1); }
結果:
[B]
在上面2的實驗過程當中,咱們知道batchRemove(Collection,true)也是求交集,因此猜測 retainAll 內部應該是調用 batchRemove(Collection,true),查看ArrayList的源碼以下:
public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, true); }