前提需要明白List是引用类型,引用类型采用引用传递。

  我们经常会遇到一些需求求集合的交集、差集、并集。例如下面两个集合:

        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中没有的元素:

    public static void test3(List list1, List list2) {
list1.removeAll(list2);
System.out.println(list1);
}

结果:

[A]

查看ArrayList的removeAll的源码

    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;
}

  是重新定义elementData数组的元素,下面代码的作用是将本集合中不包含另一个集合的元素重新加入元素,以此实现删除的功能(注意上面调用的方法传的参数是false,也就是不包含的元素得以保留,实现差集的功能)

if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];

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);
}

java 两个list 交集 并集 差集 去重复并集的更多相关文章

  1. (java/javascript) list 交集 并集 差集 去重复并集

    java list 交集 并集 差集 去重复并集 package com; import java.util.ArrayList; import java.util.Iterator; import ...

  2. 如何求ArrayList集合的交集 并集 差集 去重复并集

    需要用到List接口中定义的几个方法: addAll(Collection<? extends E> c) :按指定集合的Iterator返回的顺序将指定集合中的所有元素追加到此列表的末尾 ...

  3. java list 交集 并集 差集 去重复并集

    package com; import java.util.ArrayList;import java.util.Iterator;import java.util.List; public clas ...

  4. java List交集 并集 差集 去重复并集

    首先定义两个list List list1 =new ArrayList(); list1.add("); list1.add("); list1.add("); Lis ...

  5. java中set的交集、差集、并集的简单实现

    实现思路很简单,直接上代码: package test; import java.util.HashSet; import java.util.Set; public class Test { pub ...

  6. java8 stream两个集体交集、差集、并集操作

    业务场景: 页面左右两个datagrid,双击左边datagrid行,移动到右边datagrid,右边datagrid行双击,移动到左边datagrid 点击保存,提交修改的数据到后台 后台要把查询到 ...

  7. Python set运算 集合差集,并集,交集,list去重复

    在没有发现方便的set运算之前,都是用遍历list查找两个集合的差别. 比如, 找list1和list2的差集 for i in list1: if not i in list2: print i 现 ...

  8. LINUX Shell 下求两个文件交集和差集的办法

    http://blog.csdn.net/autofei/article/details/6579320 假设两个文件FILE1和FILE2用集合A和B表示,FILE1内容如下: a b c e d ...

  9. java用最少循环求两个数组的交集、差集、并集

    import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List ...

随机推荐

  1. Leetcode 217.存在重复元素 By Python

    给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3,1] 输出: true ...

  2. 【BZOJ2302】[HAOI2011]Problem C(动态规划)

    [BZOJ2302][HAOI2011]Problem C(动态规划) 题面 BZOJ 洛谷 题解 首先如果\(m=0\)即没有特殊限制的话,那么就和这道题目基本上是一样的. 然而这题也有属于这题的性 ...

  3. yml实例

    producer.yml apiVersion: v1kind: Podmetadata:name: producer-consumerspec:containers:- image: busybox ...

  4. 老铁,这年头得玩玩这个:Git基本操作【github】

    GitHub创建项目 本地创建项目 1.初始化配置,设置仓库人员的用户名和邮箱地址,这一步必不可少 git config --global user.name "uncleyong" ...

  5. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

  6. 灯 & 树

    这回是两道题一起... [USACO09NOV]灯 [中山市选2009]树 题意:给您一些灯,以及一些边.每次改变一盏灯的时候,它相邻的灯也会变.求把灯状态全部转换的最小操作次数. 解: 解异或方程组 ...

  7. Django-Ajax及跨域请求

    Ajax准备知识:json 什么是json? 定义: JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式.它基于 ECMAScript (w ...

  8. SIFT算法详解

    尺度不变特征变换匹配算法详解Scale Invariant Feature Transform(SIFT)Just For Fun zdd  zddmail@gmail.com or (zddhub@ ...

  9. springcloud的配置文件的读取顺序

    SpringBoot默认支持properties和YAML两种格式的配置文件.前者格式简单,但是只支持键值对.如果需要表达列表,最好使用YAML格式.SpringBoot支持自动加载约定名称的配置文件 ...

  10. C#使用Ado.Net读写数据库

    1.使用DataReader方式读取资料 [csharp] view plain copy String connString = ConfigurationManager.ConnectionStr ...