今天在优化项目中的考勤同步功能时遇到将考勤机中的数据同步到数据库,
两边都是几万条数据的样子,老代码的做法差不多半个小时,优化后我本机差不多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中不存在的数据集
来源:https://blog.csdn.net/u013675978/article/details/86620411


猜你喜欢
- 什么是方法?System.out.println(),那么它是什么呢?系统类里的,对象out,输出方法printlnJava方法是语句的集合
- 前言在这篇文章里,最后总结处,我说了会讲讲循环依赖中,其中一个类添加@Async有可能会导致注入失败而抛异常的情况,今天就分析一下。一、异常
- 本文将是JVM 性能优化系列的第二篇文章(第一篇:传送门),Java 编译器将是本文讨论的核心内容。本文中,作者(Eva Andreasso
- 将Excel转为PDF格式时,通常情况下转换出来的PDF页面都是默认的宽度大小;如果Excel表格数据的设计或布局比较宽或者数据内较少的情况
- 在项目中我们肯定不能使用Spring自己生成的登录页面,而要用我们自己的登录页面,下面讲一下如何自定义登录页面,先看下配置<sec:h
- 废话不多说了,直接给大家贴代码了,具体代码如下所述:package com.example.esp8266;import java.io.I
- 前言在使用Webview进行滑动操作时,从屏幕可见区域外向内滑动时,会出现webview区域闪烁的问题(反之也是),本文将提供一种解决方案。
- 本文实例为大家分享了android通过usb读取U盘的具体代码,供大家参考,具体内容如下1.关联 compile ‘com.github.m
- 一、前言我们在日常开发中,避不开的就是参数校验,有人说前端不是会在表单中进行校验的吗?在后端中,我们可以直接不管前端怎么样判断过滤,我们后端
- 说明:本文记录如何在Idea下,利用Maven管理项目,并整合SSM(Spring + Spring MVC +Mybatis)框架,实现简
- 本文实例讲述了Android编程显示网络上的图片的方法。分享给大家供大家参考,具体如下:在Android中显示网络上的图片,需要先根据url
- java实现数据加密问题,具体代码如下所示:package Array;import java.util.Scanner;/*某个公司采用电
- 最近再开发中遇到需要将文件上传到Linux服务器上,至此整理代码笔记。此种连接方法中有考虑到并发问题,在进行创建FTP连接的时候
- 为什么Android要申请权限简单说下在Android6.0及6.0以上一些google认为涉及“危险和用户隐私”的一些权限不仅要做清单文件
- HttpWebRequest 是一个Http 请求类,继承于 WebRequest。WebRequest 是一个抽象类,能够对统一资源标识符
- 前言上文讲的MyBatis部署运行且根据官网运行了一个demo:一步到位部署运行MyBatis3源码<保姆级>jdbc再贴一个J
- Qt的版本发布越来越频繁,Qt6发布已经有一段时间了,越来越多的人咨询之前的代码是否可以增加对Qt6的支持,包括开源的项目QWidgetDe
- C++ 线程(串行 并行 同步 异步)详解看了很多关于这类的文章,一直没有总结。不总结的话就会一直糊里糊涂,以下描述都是自己理解
- 标题Gradle构建问题切换到Project工程下.idea/gradle.xml添加属性<option name="del
- 第一个案例为大家分享了Android遍历特定目录下所有文件,包含子目录的,并删除最新创建的。 private boolean deleteL