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

网友投稿 868 2022-11-20


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 firstArrayList = new ArrayList();

List secondArrayList = new ArrayList();

List defectList = new ArrayList();//差集List

List collectionList = new ArrayList();//交集List

List unionList = new ArrayList();//去重并集List

try {

firstArrayList.add("aaa");

firstArrayList.add("bbb");

firstArrayList.add("ccc");

firstArrayList.add("ddd");

http:// secondArrayList.add("bbb");

secondArrayList.add("ccc");

secondArrayList.add("eee");

// 获取差集

defectList = receiveDefectList(firstArrayList, secondArrayList);

Iterator defectIterator = defectList.iterator();

System.out.println("===================差集===================");

while(defectIterator.hasNext()) {

System.out.println(defectIterator.next());

}

// 获取交集

collectionList = receiveCollectionList(firstArrayList, secondArrayList);

Iterator collectionIterator = collectionList.iterator();

System.out.println("===================交集===================");

while(collectionIterator.hasNext()) {

System.out.println(collectionIterator.next());

}

// 获取去重并集

unionList = receiveUnionList(firstArrayList, secondArrayList);

Iterator unionIterator = unionList.iterator();

System.out.println("===================去重并集===================");

while(unionIterator.hasNext()) {

System.out.println(unionIterator.next());

}

}catch(Exception e) {

e.printStackTrace();

}

}

/**

* @方法描述:获取两个ArrayLhttp://ist的差集

* @param firstArrayList 第一个ArrayList

* @param secondArrayList 第二个ArrayList

* @return resultList 差集ArrayList

*/

public static List receiveDefectList(List firstArrayList, List secondArrayList) {

List resultList = new ArrayList();

LinkedList result = new LinkedList(firstArrayList);// 大集合用linkedlist

HashSet othHash = new HashSet(secondArrayList);// 小集合用hashset

Iterator iter = result.iterator();// 采用Iterator迭代器进行数据的操作

while(iter.hasNext()){

if(othHash.contains(iter.next())){

iter.remove();

}

}

resultList = new ArrayList(result);

return resultList;

}

/**

* @方法描述:获取两个ArrayList的交集

* @param firstArrayList 第一个ArrayList

* @param secondArrayList 第二个ArrayList

* @return resultList 交集ArrayList

*/

public static List receiveCollectionList(List firstArrayList, List secondArrayList) {

List resultList = new ArrayList();

LinkedList result = new LinkedList(firstArrayList);// 大集合用linkedlist

HashSet othHash = new HashSet(secondArrayList);// 小集合用hashset

Iterator iter = result.iterator();// 采用Iterator迭代器进行数据的操作

while(iter.hasNext()) {

if(!othHash.contains(iter.next())) {

iter.remove();

}

}

resultLhttp://ist = new ArrayList(result);

return resultList;

}

/**

* @方法描述:获取两个ArrayList的去重并集

* @param firstArrayList 第一个ArrayList

* @param secondArrayList 第二个ArrayList

* @return resultList 去重并集ArrayList

*/

public static List receiveUnionList(List firstArrayList, List secondArrayList) {

List resultList = new ArrayList();

Set firstSet = new TreeSet(firhttp://stArrayList);

for(String id : secondAzdfExrrayList) {

// 当添加不成功的时候 说明firstSet中已经存在该对象

firstSet.add(id);

}

resultList = new ArrayList(dawjidSet);

return resultList;

}

}

打印结果:

===================差集===================

aaa

ddd

===================交集===================

bbb

ccc

=================去重并集==================

aaa

bbb

ccc

ddd

eee

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:idea插件篇之java内存分析工具(JProfiler)的使用
下一篇:IDEA编写JavaWeb出现乱码问题解决方案
相关文章

 发表评论

暂时没有评论,来抢沙发吧~