-
2019-04-01 14:59:29
List<String> list1 = new ArrayList<String>(){{add("a");add("b");add("c");add("d");}}; List<String> list2 = new ArrayList<String>(){{add("e");add("f");add("d");add("c");add("g");}}; //将第一个List赋给第三个List List<String> list = new ArrayList<>(list1); //将第二个List放进第三个List for(int i = 0;i<list2.size();i++) { //如果第三个List已经存在,则不添加,如果不存在就添加 if(!list.contains(list2.get(i))) {//contains是包含的意思,这个if加了!,意思是不包含 list.add(list2.get(i)); } } //删除第三个里面包含第一个和第二个List的元素 for(int i = 0;i<list.size();i++) { //将第一,第二个List和第三个比较,如果第一第二个都有的,则从第三个删除 if(list1.contains(list.get(i)) && list2.contains(list.get(i))) { list.remove(i); i--;//如果删除了一个元素,就继续从这个数组下标开始比较 } } System.out.println(list); }
更多相关内容 -
java 找出两个list中不同值
2021-02-26 08:22:42展开全部可以通过遍历两个string数组来实现。代码e5a48de588b63231313335323631343130323136353331333365656633如下:package com.czp.test;import java.util.ArrayList;import java.util.List;public class ...展开全部
可以通过遍历两个string数组来实现。
代码e5a48de588b63231313335323631343130323136353331333365656633如下:
package com.czp.test;
import java.util.ArrayList;
import java.util.List;
public class TestList {
public static void main(String[] args) {
List list1 = new ArrayList();
List list2 = new ArrayList();
for (int i = 0; i < 10000; i++) {
list1.add("test"+i);
list2.add("test"+i*2);
}
getDiffrent(list1,list2);
//输出:total times 2566454675
}
/**
* 获取两个List的不同元素
* @param list1
* @param list2
* @return
*/
private static List getDiffrent(List list1, List list2) {
long st = System.nanoTime();
List diff = new ArrayList();
for(String str:list1)
{
if(!list2.contains(str))
{
diff.add(str);
}
}
System.out.println("total times "+(System.nanoTime()-st));
return diff;
}
}
源代码截图:
扩展资料:
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等 。
参考资料:百度百科-网页链接
-
如何使用Java最快捷的找出两个大量数据List集合的不同元素
2020-03-06 16:56:20本篇博客介绍了几种能够找出List集合中不同元素的方法, 并通过性能对比和源码分析的方式来介绍几种方式的区别, 希望大家遇到类似的需求能够选择合适的方法,少走弯路近期,花了一段时间开发生产环境中的自动补数工具,来替代我完成繁琐无趣的人肉运维工作. 这款补数工具有这样一个小的需求点: 快速的找出两个相似度非常高的List集合里的不同元素. (每个集合大约有200W个元素,并且随着业务的扩展集合的数据量会越来越大,两个集合之间可能只有几个元素不同) 期间,踩了一点小坑,把入坑到脱坑的过程分享给大家,希望大家遇到类似的需求时能选取合适的方法,少走弯路
本篇博客相关代码已经上传到github,需要的请自行下载:
本篇博客要点如下:
一.测试数据集准备
测试数据为A集合: 1千, 1万, 10万,1百万, 1千万的数据量.
B集合比A集合多十条数据.
测试数据使用空字符串 + 自然数的方式.造数方法如下:
/** * 制造任意个元素的的List集合 * @param size List集合的size * @return List<String> */ private static List<String> dataList(int size) { List<String> dataList = new ArrayList<>(); for (int i = 0; i < size; i++) { dataList.add("" + i); } return dataList; }
我们采用以下方法打印出两个集合不同的元素,
以此来确保我介绍到的每种方法都可以正确找到两个集合中的不同元素/** * 遍历集合,打印出每个元素 * @param list List集合 */ private static void traverse(List<String> list) { for (String str : list) { System.out.print(str + " "); } System.out.println(); }
二.使用Java自带的api比较不同
这是我最初使用的办法,原因,代码量少,不用动脑.
核心代码只有以下四行:/* 通过下面的四行代码, 我们得到了以下三个集合 ListA : 集合A与集合B不同的元素 ListB : 集合B与集合A不同的元素 ListABak : 集合A与集合B相同的元素 乍一看是不是非常高效快捷? 别急,请看后面的性能验证 */ List<String> listABak = new ArrayList<>(listA); // 复制A集合作为备份 listB.removeAll(listA); // B集合与A集合的不同元素 listABak.removeAll(listB); // A集合与B集合的相同元素 listA.removeAll(listABak); // A集合与B集合的不同元素
数量级为1000条数据性能如下(对比耗时单位全部为毫秒,后续不再赘述) ,还算正常
数量级为10000条数据性能如下,也还可以接受
数量级为100000条数据性能如下,这里就已经比较慢了
数据量100W,1000W的性能结果,我就不再贴出来了
因为,100W的数据量,我跑了一下午没跑出来!!!
按照这个效率,1000W估计能跑到年底~为什么在数据量增大的时候,这种方法性能下降的这么明显?
我们不妨来看一下removeAll的源码:public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); boolean modified = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); modified = true; } } return modified; }
通过源码我们可以看到,该方法是使用迭代器对集合进行遍历
第一层迭代需要执行 listA.size()次,里面调用了contains方法来确定集合B是否含有该元素,
再看contains方法的源码public boolean contains(Object o) { return indexOf(o) >= 0; }
继续追踪:indexOf源码:
public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
可以看到,indexOf方法里又进行了一层遍历.
平均每次遍历要进行listB.size() / 2次计算,
假设集合A的元素个数为m,集合B的元素个数为n
我们可以得到结论,运算次数为 m *(n/2)
对于100W数据量来说,假设你的计算机每秒能够执行1千万次运算,
也需要27.8个小时才能对比出来…
所以大数据量时千万不要滥用该方法!!三. 笨比操作二 ---- 使用双层遍历比较不同
/* 该方法实际上就是将removeAll的实现逻辑用自己的方式写出来 所以执行效率,运行结果和上一种方法没什么区别,这里只贴代码出来,不再赘述 */ private static void stupidMethod2(List<String> listA, List<String> listB) { System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); List<String> differList = new ArrayList<>(); long startTime = System.currentTimeMillis(); for (String str : listB) { if (!listA.contains(str)) { differList.add(str); } } traverse(differList); long endTime = System.currentTimeMillis(); System.out.println("使用双层遍历方法 对比耗时: " + (endTime - startTime)); }
四.人类方法 ---- 借助Map集合找出不同
该方法的总体思路为:
以List集合里的元素作为Map的key,
元素出现的次数作为Map的Value,
那么两个List集合的不同元素为Map集合中value值为1,所对应的键.
把所有value值为1的键找出来,我们就得到了两个List集合不同的元素
代码如下:/** * 借助Map来获取listA、listB的不同元素集合 * * @param listA 集合A * @param listB 集合B * @return list<String> */ public static List<String> getDifferListByMap(List<String> listA, List<String> listB) { System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); List<String> differList = new ArrayList<>(); Map<String, Integer> map = new HashMap<>(); long beginTime = System.currentTimeMillis(); for (String strA : listA) { map.put(strA, 1); } for (String strB : listB) { Integer value = map.get(strB); if (value != null) { map.put(strB, ++value); continue; } map.put(strB, 1); } for (Map.Entry<String, Integer> entry : map.entrySet()) { if (entry.getValue() == 1) { //获取不同元素集合 differList.add(entry.getKey()); } } traverse(differList); long endTime = System.currentTimeMillis(); System.out.println("使用map方式遍历, 对比耗时: " + (endTime - beginTime)); return differList; }
程序运行情况如下:
集合元素个数为1000时:
集合元素个数为10000时,这里已经比上面的方法快不少了
集合元素个数为100000时,性能的提升显而易见
集合元素个数为1百万时,依然很快!
集合元素为1千万时,也只需要15S就能对比出结果
我们可以看到,使用map集合的方式寻找不同元素,时间增长基本上是线性的
它的时间复杂度为O(m)
而上面的remove方式和双层循环遍历的时间复杂度为O(m * n)
所以,选用这种方式带来的性能收益随着集合元素的增长而增长全量代码分享
以上实例中涉及到的全量代码如下:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author xmr * @date 2020/3/5 8:18 * @description */ public class ListTest { public static void main(String[] args) { List<String> listA = dataList(10000000); List<String> listB = dataList(10000000 + 10); // stupidMethod(listA, listB); // stupidMethod2(listA, listB); getDifferListByMap(listA, listB); } private static void stupidMethod2(List<String> listA, List<String> listB) { System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); List<String> differList = new ArrayList<>(); long startTime = System.currentTimeMillis(); for (String str : listB) { if (!listA.contains(str)) { differList.add(str); } } traverse(differList); long endTime = System.currentTimeMillis(); System.out.println("使用双层遍历方法 对比耗时: " + (endTime - startTime)); } /** * 遍历集合,打印出每个元素 * * @param list List集合 */ private static void traverse(List<String> list) { for (String str : list) { System.out.print(str + " "); } System.out.println(); } private static void stupidMethod(List<String> listA, List<String> listB) { System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); List<String> listABak = new ArrayList<>(listA); // 复制A集合作为备份 long startTime = System.currentTimeMillis(); listB.removeAll(listA); // B集合与A集合的不同元素 traverse(listB); long endTime = System.currentTimeMillis(); System.out.println("直接调用java api 方法 对比耗时: " + (endTime - startTime)); // listABak.removeAll(listB); // A集合与B集合的相同元素 // listA.removeAll(listABak); // A集合与B集合的不同元素 } /** * 制造任意个元素的的List集合 * * @param size List集合的size * @return List<String> */ private static List<String> dataList(int size) { List<String> dataList = new ArrayList<>(); for (int i = 0; i < size; i++) { dataList.add("" + i); } return dataList; } /** * 借助Map来获取listA、listB的不同元素集合 * * @param listA 集合A * @param listB 集合B * @return list<String> */ public static List<String> getDifferListByMap(List<String> listA, List<String> listB) { System.out.println("数量级为 " + listA.size() + "集合的不同元素为"); List<String> differList = new ArrayList<>(); Map<String, Integer> map = new HashMap<>(); long beginTime = System.currentTimeMillis(); for (String strA : listA) { map.put(strA, 1); } for (String strB : listB) { Integer value = map.get(strB); if (value != null) { map.put(strB, ++value); continue; } map.put(strB, 1); } for (Map.Entry<String, Integer> entry : map.entrySet()) { if (entry.getValue() == 1) { //获取不同元素集合 differList.add(entry.getKey()); } } traverse(differList); long endTime = System.currentTimeMillis(); System.out.println("使用map方式遍历, 对比耗时: " + (endTime - beginTime)); return differList; } }
一点思考
如今,越来越多的公司在面试的时候考察程序员的数据结构与算法 曾经,我也一度觉得面试造火箭,工作拧螺丝.. 认为通过这种方式选拔人才有失偏颇 但实际上, 算法与数据结构,计算机基本知识这些基础性的东西,最能体现出功底和成长空间. 功能是个人百度一下都能实现. 但是实现的优雅,高效却是一门学问. 在复杂的生产环境中,可能一行糟糕的代码实现给用户带来的是灾难级别的体验. 因此,我们应该多问问自己代码这样写合不合适? 对自己写的代码心存敬畏,对自己严格要求
-
两个list集合找出相同元素和不同元素
2021-03-11 16:16:27package ...import java.util.Collection;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.Map;public class Colle...package com.zkdj.shiro.utils;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
public class CollectionUtil {
private CollectionUtil() {
}
/**
* 找出第一个集合中不存在与第二个集合的元素
*
* @param collmax
* @param collmin
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Collection getDifferent(Collection collmax, Collection collmin) {
//使用LinkedList防止差异过大时,元素拷贝
Collection csReturn = new LinkedList();
Collection max = collmax;
Collection min = collmin;
//先比较大小,这样会减少后续map的if判断次数
// if (collmax.size() < collmin.size()) {
// max = collmin;
// min = collmax;
// }
//直接指定大小,防止再散列
Mapmap = new HashMap(max.size());
for (Object object : max) {
map.put(object, 1);
}
for (Object object : min) {
if (map.get(object) == null) {
// csReturn.add(object);
} else {
map.put(object, 2);
}
}
for (Map.Entryentry : map.entrySet()) {
if (entry.getValue() == 1) {
csReturn.add(entry.getKey());
}
}
Iteratorit = csReturn.iterator() ;
while(it.hasNext()) {
String str = it.next() ;
if(str.equals(" ")||str.equals("")) {
it.remove();//此处删除集合中的一个元素
}
}
return csReturn;
}
/**
* 找出两个集合中相同的元素
*
* @param collmax
* @param collmin
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Collection getSame(Collection collmax, Collection collmin) {
//使用LinkedList防止差异过大时,元素拷贝
Collection csReturn = new LinkedList();
Collection max = collmax;
Collection min = collmin;
//先比较大小,这样会减少后续map的if判断次数
if (collmax.size() < collmin.size()) {
max = collmin;
min = collmax;
}
//直接指定大小,防止再散列
Mapmap = new HashMap(max.size());
for (Object object : max) {
map.put(object, 1);
}
for (Object object : min) {
if (map.get(object) != null) {
csReturn.add(object);
}
}
return csReturn;
}
/**
* 获取两个集合的不同元素,去除重复
*
* @param collmax
* @param collmin
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static Collection getDiffentNoDuplicate(Collection collmax, Collection collmin) {
return new HashSet(getDifferent(collmax, collmin));
}
}
-
Java对比两个list并找出其中不同的值(list里面的具体类单独抽出不同字段)
2020-12-22 16:58:47今天凯哥交给我一个任务,在报警模版中对比新旧两个数据,找出其中不同的部分,之前是把不同的数据转string做了对比,并没有对list中的对象做判断,修改完之后记录一下。list做对比,如果 list 里面的数据是乱序的,... -
Java8 Stream对两个 List 遍历匹配数据的优化处理操作
2021-03-13 18:17:35使用场景,有两个List>集合,第一个集合的所有元素都是需要保留的。第一个集合的值为:{name=张三丰1, id=1}{name=张三丰2, id=2}{name=张三丰3, id=3}{name=张三丰4, id=4}{name=张三丰5, id=5}{name=张三丰6, ... -
【Java】获取两个List中不同的数据(效率非常不错)
2019-06-26 11:47:56项目背景 刚好项目要快速对比两张表的不同数据,但是提供的是id的列表(list),另外在数据库中,所以这里想出...1、list1中有97277条数据,list2中有37894条数据,两个list进行对比找出不同的数据共60000条左右,用... -
java找出2个集合相同和不同的元素(以及去除List中的重复元素)
2017-12-12 16:57:06一、找到2个集合中相同和不同的元素 此处需要使用Collection集合所提供的一个方法:removeAll(Cellection list) 实现代码如下: import java.util.ArrayList; import java.util.Collection; import java.util.... -
java List流操作 一行代码找出两个List中的相同元素
2020-07-18 19:00:00ids.stream().filter(s -> ids2.contains(s)).collect(Collectors.toList()); ids和ids2都是两个ArrayList -
高效的找出两个List中的不同元素
2020-01-03 16:08:02高效的找出两个List中的不同元素 import lombok.extern.slf4j.Slf4j; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** * - File Name:ListTest * - @Author: ... -
Java根据list中对象的属性找出list重复数据
2021-04-20 15:12:57Java根据list中对象的属性找出list重复数据或去除list重复数据 按照思路进行对应的修改即可 第一种方法 public static void main(String[] args) { List<Student> testList = new ArrayList<Student>()... -
java找出两个集合中相同和不同的元素
2020-08-23 20:49:441.CollectionUtils.diff(Collection c1, Collection c2),返回集合c2不包含集合c1... List<String> list1 = new ArrayList<String>(); list1.add("1"); list1.add("2"); List<String> list2 = new -
告土鳖的循环对比,java8 Stream 取出两个list中相同部分
2021-03-10 07:51:12privatestaticfinalListlist=Lists.newArrayList("1","2","3","4","5");privatestaticfinalListlist2=Lists.newArrayList("0","1","2","3","4");@Testpublicvoidstream(){Listl=(List)list.stream(... -
找出两个List集合重复的元素
2019-02-13 20:26:56前几天,有个同事问我说怎么找出两个List集合中重复的元素,我当时就说一个集合在外面循环,一个集合在内循环,如果两个元素相等了,就找出来了,我回来一想还是不对,要是数据非常多,这样循环下去,服务器会卡死的... -
java两个list中保存bean对象,找出其中某一属性不同的元素
2017-11-28 15:37:29在java中运用List集合保存对象,如果想找到两个list中不同的部分,可以用ArrayList的contains方法,遍历每一个对象,判断是否是相等的,如下: public static void getUncontain(List list1, List list2){ for... -
java比较两个List中的不同元素 查找两个集合中的不同元素
2019-04-15 13:04:15Java 查找两个集合中的相同元素和不同元素 假设有这个集合, List<Category> metaCategs , 只要categId 在下面数组中,就从metaCategs中移除 Integer[] removeCategIds =ne... -
java List Map数据对比 找出相同和不同的内容
2015-06-02 17:02:23原先搞出来的是 弄了两个List集合进行匹配代码就不贴了,说一下思路把 List list1=new ArrayList();//新数据 List list2=new ArrayList();//数据库数据 GongGl //公共类 如果list1>list2则说明有新数据,然后拿着... -
java8 stream 两个不同对象list取差集
2021-03-24 17:31:24qwWxUserModelList里面有包含tagIdList,排除掉得集合 for (QwWxUserModel qwWxUserModel : qwWxUserModelList) { List newTagModel = qwWxUserModel.getTagIdList().stream().filter(it->!tagIdList.contains(it.... -
两个List集合取相同重复数据的方法
2021-02-27 22:55:45以下是两个list取重复的代码:public static void main(string[] args) {list list1 = new arraylist();for (int i = 0; i < 5; i++) {list1.add(i);}list list2 = new arraylist();for (int i = 2; i < 8; i+... -
java 查找list中重复数据实例详解
2021-02-12 20:32:23java 查找list中重复数据实例详解需求:查找一个list集合中所有重复的数据,重复的数据可能不止一堆,比如:aa, bb, aa, bb, cc , dd, aa这样的数据。如果有重复数据,则给这些重复数据加上编号,上述数据改为:aa1,... -
Java两个list找出相同部分、多余部分和少的部分(业务操作建立在此方法上)
2019-03-28 17:14:47废话不多说,直接上代码 public static void ... //以aList为准,aList比bList多余的部分添加,少的部分删除,相同的部分更新 List<String> aList=new ArrayList(); List<String> bList=new Array... -
java8 过滤两个list集合中相同的元素 并返回相同list集合
2020-12-15 21:29:51List<FindByStudentForPayResult> result = studentForPayResultList.stream().filter( (studentForPayResult) ->payList.stream().map(BaseActivePay::getStudentId).collect(Collectors.toList()).... -
java 如何获取得到两个list中不同的数据
2015-07-24 16:30:31如何移除两个List中相同的数据,比如说现在有groupNameList 跟 defaulGrouptNameList两个字符串数组: 1、先复制,clone() ArrayList a = (ArrayList) groupNameList.clone(); 2、再移除,remove()... -
java 快速取出两个list中实体某个属性值相同的实体和不同的实体
2020-03-26 13:56:41引言:在项目的开发过程中经常要用到list的结构,如何快速的提取出list<...先定义两个list: List<String> list1 = new ArrayList<>(); list1.add("1"); list1.add("2"); List<String&g... -
java根据list中对象的属性找出list重复数据或去除list重复数据
2017-11-17 15:12:50在实际开发中,经常会遇到需要找出(删除)一个list中某些元素的属性相同的元素,或者两个list中某些元素的属性相等的元素,这种方法很多,这里整理列出一些: 废话不说,上代码,有注释掉的你们自己看import java.... -
java怎样把两个list里边相同的数据取出
2019-01-31 10:05:19import java.util.ArrayList;...import java.util.List; public class Contains { public static void main(String[] args) { List<Integer> list1=new ArrayList<>(); ... -
Java根据list中对象的属性找出list重复数据或去除list重复数据
2019-06-09 06:35:27在实际开发中,经常会遇到需要找出(删除)一个list中某些元素的属性相同的元素,或者两个list中某些元素的属性相等的元素,这种方法很多,这里整理列出一些: 废话不说,上代码,有注释掉的你们自己看 import java....