java较大数据量取差集,list.removeAll性能优化详解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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性能优化详解就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。