前提需要明白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. HDU - 1160 (FatMouse's Speed )最长上升子序列

    题意:一个元素有两个属性 w 和 sp 求在w严格递增的情况下 sp严格递减 用结构体 定义三个参数  w  sp  ix , ix是在输入时的顺序  因为我们要排序 之后把结构体数组 按从小到大排序 ...

  2. hdu 6394 Tree (2018 Multi-University Training Contest 7 1009) (树分块+倍增)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=6394 思路:用dfs序处理下树,在用分块,我们只需要维护当前这个点要跳出这个块需要的步数和他跳出这个块去 ...

  3. day25 面向对象引子

    面向对象编程所谓模子就是 类 抽象的,能知道什么属性,但是不知道属性具体值一切都是对象 有具体值 属性和技能都是根据类 模子来规范 # 人狗大战 # 角色模型 # 人的模型 def Person(na ...

  4. Eclipse Jee Oxygen安装svn插件

    转: Eclipse Jee Oxygen安装svn插件 技术标签: eclipse  svn Eclipse Jee Oxygen安装svn插件 入主题: 选择Eclipse->菜单-> ...

  5. JS面试题(二)(常见算法编程)

    1.字符串转驼峰 例如:border-bottom-color ----> borderBottomColor var str="border-bottom-color"; ...

  6. jdk8的特性stream().map()

    转: https://blog.csdn.net/sanchan/article/details/70753645 java8的optional的使用: http://www.jdon.com/ide ...

  7. kubernetes下的Nginx加Tomcat三部曲之一:极速体验

    在生产环境中,常用到Nginx加Tomcat的部署方式,如下图: 从本章开始,我们来实战kubernetes下部署上述Nginx和Tomcat服务,并开发spring boot的web应用来验证环境, ...

  8. 何谓SQL Server参数嗅探

    大家听到"嗅探"这个词应该会觉得跟黑客肯定有关系吧,使用工具嗅探一下参数,然后截获,脱裤o(∩_∩)o . 事实上,我觉得大家太敏感了,其实这篇文章跟数据库安全没有什么关系,实际上 ...

  9. X-UA-compatible浅谈

    最近了解到svg,原来它出现之前好几年,微软已经推出了vml,但是那时候却被人吐槽无数,看来过早的创新也是失败的原因之一呢~ 为什么谈到这个话题呢?因为IE史上有一个特别奇怪的浏览器IE8,它及不兼容 ...

  10. powershell 删除8天前的日志

    把以下命令保存为ps1脚本,添加到Windows计划任务中设定每天固定时间执行即可: #delete logs in specify website, just save logs in eight ...