hello,你好呀,我是灰小猿,一个超会写bug的程序猿!
最近在做项目的时候有用到对两个集合中的元素进行对比求其交集的情况,因为涉及到的数据量比较大,所以在进行求两个集合中元素交集的时候,就应该考虑到程序运行的时间消耗等问题,
所以写了四种求集合元素交集的方法 今天这篇文章主要是来记录对比一下,这四种方法使用起来的效率问题,
方法一,求两个集合的交集【普通for循环】
这种方法是最普通的进行for循环比较的方法。利用集合的contains方法,来对比第二个集合中是否存在相同的元素的方法,同时将交集结果返回。
代码示例如下:
/**
* 方法1,求两个集合的交集
*
* @param arr1
* @param arr2
* @return
*/
public List<Object> intersectionForList_1(List<Object> arr1, List<Object> arr2) {
long startTime = System.currentTimeMillis();
List<Object> result = new ArrayList<>();
for (Object arr : arr1) {
if (arr2.contains(arr)) {
result.add(arr);
}
}
long endTime = System.currentTimeMillis();
log.info("intersectionForList_1:" + (endTime - startTime));
return result;
}
方法2,求两个集合交集,(迭代器)
这种方法使用的是list集合的迭代器的方法,其实原理和for是一样的,方法的核心也和for循环是一样的,只是外层循环的方法不一样,所以它和上面第一种方法的效果是一样的。
代码示例如下:
/**
* 方法2,求两个集合交集,(迭代器)
*
* @param arr1
* @param arr2
* @return
*/
public List<Object> intersectionForList_2(List<Object> arr1, List<Object> arr2) {
long startTime = System.currentTimeMillis();
List<Object> resultList = new ArrayList<>();
List<Object> maxList;
List<Object> minList;
if (arr1.size()>arr2.size()){
maxList = arr1;
minList = arr2;
}else {
maxList = arr2;
minList = arr1;
}
Iterator<Object> iterator = maxList.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
if (minList.contains(next)){
resultList.add(next);
}
}
long endTime = System.currentTimeMillis();
log.info("intersectionForList_2:" + (endTime - startTime));
return resultList;
}
方法3,求两个集合交集,(map)
这种方法使用的是map的特性,首先将list集合中的元素依次存入一个map中去,然后再以map的get方法来判断是否存在这样的元素。
这种方法的效率最高,在10万条数据的测试下,这种方法耗时仅仅在十几毫秒,而其他方法在将近一百多毫秒。
在百万条数据进行对比处理的时候,使用map特性的方法时间消耗大概在40毫秒左右,但是其他方法要将近10秒钟,
所以在对于大量数据的处理过程中,还是非常建议使用这种方法的。
代码示例如下:
/**
* 方法3,求两个集合交集,(map)
*
* @param arr1
* @param arr2
* @return
*/
public List<Object> intersectionForList_3(List<Object> arr1, List<Object> arr2) {
long startTime = System.currentTimeMillis();
List<Object> resultList = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
arr1.forEach(a1->{
map.put(a1+"",a1);
});
arr2.forEach(a2->{
Object obj = map.get(a2 + "");
if (obj!=null){
resultList.add(obj);
}
});
long endTime = System.currentTimeMillis();
log.info("intersectionForList_3:" + (endTime-startTime));
return resultList;
}
方法4,求两个集合交集,(forEasy)
这种方法使用的是集合的foreasy特性和Java流的特性,使用这种方法可以遍历其中的一个集合,然后再使用contains方法来判断另一个集合中是否存在该集合元素,这种方法的使用效率要优于第一种和第二种方法。
代码示例如下:
/**
* 方法4,求两个集合交集,(forEasy)
* @param arr1
* @param arr2
* @return
*/
public List<Object> intersectionForList_4(List<Object> arr1, List<Object> arr2){
long startTime = System.currentTimeMillis();
List<Object> resultList = new ArrayList<>();
arr1.stream().forEach(a1->{
if (arr2.contains(a1)){
resultList.add(a1);
}
});
long endTime = System.currentTimeMillis();
log.info("intersectionForList_4:" + (endTime-startTime));
return resultList;
}
方法总结
总结一下以上四种求集合中元素交集的方法,按照在处理大量数据的效率来看,使用map集合的特性的方法效率最高,之后是使用Java流的方法,其次是使用for循环和迭代器的方法,
所以在正常情况下,还是推荐使用map的特性来进行集合中元素的对比分析和求交集的。
我是灰小猿,我们下期见!