java 较大数据量取差集,list.removeAll性能优化详解

 更新时间:2020年09月25日 10:36:04   作者:_Jason_PC_  
这篇文章主要介绍了java 较大数据量取差集,list.removeAll性能优化详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

今天在优化项目中的考勤同步功能时遇到将考勤机中的数据同步到数据库,

两边都是几万条数据的样子,老代码的做法差不多半个小时,优化后我本机差不多40秒,服务器速度会更加理想。

两个数据集取差集首先想到的方法便是List.removeAll方法,但是实验发现jdk自带的List.removeAll效率很低

List.removeAll效率低原因:

List.removeAll效率低和list集合本身的特点有关 :

List底层数据结构是数组,查询快,增删慢

1.List.contains()效率没有hashset高

arrayList.removeAll底层是for循化调用contains方法。arrayList虽然用get(index)方法查询效率高,但是若用contains方法查询对象元素,Set集合应该比List效率要高。

因为hashset的contains方法其实是先调用每个元素的hashCode()方法来返回哈希码,如果哈希码的值相等的情况下再调用equals(obj)方法去判断是否相等,只有在这两个方法所返回的值都相等的情况下,才判定这个HashSet包含某个元素,而list直接调用equals(obj)方法.所以hashset效率更高。

2.arrayList.remove()效率没有linkedList删除效率高

arrayList底层采用数组每删除一下元素数据后面的元素都要往前移动效率低消耗的资源也大,linkedList链表删除元素只要改变前后节点的位置信息

3.采用Iterator迭代器,这种方式我们仅需要对iterator进行循环,然后对需要删除的元素执行iterator.remove(iterator.next()),而无需关注下标的问题

改进代码

  LinkedList linkedList= new LinkedList(src);//大集合用linkedlist
	HashSet hashSet= new HashSet(oth);//小集合用hashset
	Iterator iter = linkedList.iterator();//采用Iterator迭代器进行数据的操作
	while(iter.hasNext()){
		if(hashSet.contains(iter.next())){
			iter.remove();			
			}	
		}

补充知识:JAVA获取两个数据量较大的ArrayList的交集、差集以及并集

测试说明:获取firstArrayList和secondArrayList的交集、差集以及并集。实际测试中firstArrayList数据量190000,secondArrayList数据量170000.效率比较高。此处只列出少量数据。测试代码如下:

import java.util.Set;
import java.util.List;
import java.util.HashSet;
import java.util.TreeSet;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.LinkedList;

public class getSet {
 
 public static void main(String args[]) {
  getList();
 }
 
 // 获取两个ArrayList的差集、交集、去重并集(数据量大小不限制)
 private static void getList() {
  List<String> firstArrayList = new ArrayList<String>();
  List<String> secondArrayList = new ArrayList<String>();
  List<String> defectList = new ArrayList<String>();//差集List
  List<String> collectionList = new ArrayList<String>();//交集List
  List<String> unionList = new ArrayList<String>();//去重并集List
  try {
   firstArrayList.add("aaa");
   firstArrayList.add("bbb");
   firstArrayList.add("ccc");
   firstArrayList.add("ddd");

   secondArrayList.add("bbb");
   secondArrayList.add("ccc");
   secondArrayList.add("eee");
   // 获取差集
   defectList = receiveDefectList(firstArrayList, secondArrayList);
   Iterator<String> defectIterator = defectList.iterator();
   System.out.println("===================差集===================");
   while(defectIterator.hasNext()) {
    System.out.println(defectIterator.next());
   }
   // 获取交集
   collectionList = receiveCollectionList(firstArrayList, secondArrayList);
   Iterator<String> collectionIterator = collectionList.iterator();
   System.out.println("===================交集===================");
   while(collectionIterator.hasNext()) {
    System.out.println(collectionIterator.next());
   }
   // 获取去重并集
   unionList = receiveUnionList(firstArrayList, secondArrayList);
   Iterator<String> unionIterator = unionList.iterator();
   System.out.println("===================去重并集===================");
   while(unionIterator.hasNext()) {
    System.out.println(unionIterator.next());
   }
  }catch(Exception e) {
   e.printStackTrace();
  }
 }
 
 /**
  * @方法描述:获取两个ArrayList的差集
  * @param firstArrayList 第一个ArrayList
  * @param secondArrayList 第二个ArrayList
  * @return resultList 差集ArrayList
  */
 public static List<String> receiveDefectList(List<String> firstArrayList, List<String> secondArrayList) {
  List<String> resultList = new ArrayList<String>();
  LinkedList<String> result = new LinkedList<String>(firstArrayList);// 大集合用linkedlist 
  HashSet<String> othHash = new HashSet<String>(secondArrayList);// 小集合用hashset 
  Iterator<String> iter = result.iterator();// 采用Iterator迭代器进行数据的操作 
  while(iter.hasNext()){ 
   if(othHash.contains(iter.next())){ 
    iter.remove();   
   }  
  } 
  resultList = new ArrayList<String>(result);
  return resultList;
 }
 
 /**
  * @方法描述:获取两个ArrayList的交集
  * @param firstArrayList 第一个ArrayList
  * @param secondArrayList 第二个ArrayList
  * @return resultList 交集ArrayList
  */
 public static List<String> receiveCollectionList(List<String> firstArrayList, List<String> secondArrayList) {
  List<String> resultList = new ArrayList<String>();
  LinkedList<String> result = new LinkedList<String>(firstArrayList);// 大集合用linkedlist 
  HashSet<String> othHash = new HashSet<String>(secondArrayList);// 小集合用hashset 
  Iterator<String> iter = result.iterator();// 采用Iterator迭代器进行数据的操作 
  while(iter.hasNext()) {
   if(!othHash.contains(iter.next())) { 
    iter.remove();   
   }  
  }
  resultList = new ArrayList<String>(result);
  return resultList;
 }
 
 /**
  * @方法描述:获取两个ArrayList的去重并集
  * @param firstArrayList 第一个ArrayList
  * @param secondArrayList 第二个ArrayList
  * @return resultList 去重并集ArrayList
  */
 public static List<String> receiveUnionList(List<String> firstArrayList, List<String> secondArrayList) {
  List<String> resultList = new ArrayList<String>();
  Set<String> firstSet = new TreeSet<String>(firstArrayList);
  for(String id : secondArrayList) {
   // 当添加不成功的时候 说明firstSet中已经存在该对象
   firstSet.add(id);
  }
  resultList = new ArrayList<String>(dawjidSet);
  return resultList;
 }
}

打印结果:

===================差集===================
aaa
ddd
===================交集===================
bbb
ccc
=================去重并集==================
aaa
bbb
ccc
ddd
eee

说明,取差集指的是取firstArrayList中存在但secondArrayList中不存在的数据集

以上这篇java 较大数据量取差集,list.removeAll性能优化详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 全面剖析java中的注解(Annotation)

    全面剖析java中的注解(Annotation)

    一个词就可以描述注解,那就是元数据,即一种描述数据的数据。所以,可以说注解就是源代码的元数据。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • ConditionalOnProperty配置swagger不生效问题及解决

    ConditionalOnProperty配置swagger不生效问题及解决

    这篇文章主要介绍了ConditionalOnProperty配置swagger不生效问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • springboot项目打成war包部署到tomcat遇到的一些问题

    springboot项目打成war包部署到tomcat遇到的一些问题

    这篇文章主要介绍了springboot项目打成war包部署到tomcat遇到的一些问题,需要的朋友可以参考下
    2017-06-06
  • java并发容器CopyOnWriteArrayList实现原理及源码分析

    java并发容器CopyOnWriteArrayList实现原理及源码分析

    这篇文章主要为大家详细介绍了java并发容器CopyOnWriteArrayList实现原理及源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Java数组传递及可变参数操作实例详解

    Java数组传递及可变参数操作实例详解

    这篇文章主要介绍了Java数组传递及可变参数操作,结合实例形式详细分析了java数组参数传递与可变参数相关使用技巧,需要的朋友可以参考下
    2019-09-09
  • 如何自动生成Mybatis的Mapper文件详解

    如何自动生成Mybatis的Mapper文件详解

    这篇文章主要给大家介绍了关于如何自动生成Mybatis的Mapper文件的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • IntelliJ IDEA2020.3详细安装教程

    IntelliJ IDEA2020.3详细安装教程

    这篇文章主要介绍了IntelliJ IDEA2020.3详细安装教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Java实现简单文件过滤器功能

    Java实现简单文件过滤器功能

    下面小编就为大家分享一篇Java实现简单文件过滤器功能,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Mybatis环境搭建及文件配置过程解析

    Mybatis环境搭建及文件配置过程解析

    这篇文章主要介绍了Mybatis环境搭建及文件配置过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Java以编程方式实现JAR文件的创建

    Java以编程方式实现JAR文件的创建

    在这篇文章中,我们将为大家详细介绍一下利用Java语言以编程方式创建jar文件的过程。文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-07-07

最新评论