java 两个list 交集 并集 差集 去重复并集

  

  前提须要明白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); }
相关文章
相关标签/搜索