解决两个List求交集 retainAll()超级慢的方法

  |   0 评论   |   0 浏览

例如List aa 和List bb,要求两个列表的交集

数据量上百万的时候retainAll()超级超级慢,没有解决办法,因为reatainAll的原理就是遍历外层列表比如aa(aa通常是数量较少的列表),再在循环里判断bb是否包含当前正遍历到的元素aa.get(i),而判断是否包含时contains方法又是一个很笨重的办法,它的原理是去获取元素的下标indexOf,即在列表中依次遍历匹配目标元素直至找到相同的元素...太慢了...慢的我失去耐心等不到结果...

但是可以切换思路,换个方法解决求交集的问题。

把List转换为Set再进行取交集。

package com.songaw.mytest;

import java.util.*;

/**
 * @author songanwei
 * @description todo
 * @date 2022/3/21
 */
public class MyList2 {
    public static void main(String[] args) {
        List<String> uidList=new ArrayList<>();
        List<String> openingRecordRoomUids = new ArrayList<>();
        for(int i=0;i<50000;i++){

            String str=UUID.randomUUID().toString().replaceAll("-","");
            if(i<500) {
                uidList.add(str);
            }
            if(i%2==0||i>500) {
                openingRecordRoomUids.add(str);
            }

        }
        Collections.shuffle(openingRecordRoomUids);
        long time=System.currentTimeMillis();

        HashSet  set=new HashSet(uidList);
        HashSet  set2=new HashSet(openingRecordRoomUids);
        //底层使用的HashMap的containsKey方法,它使用hashcode查找集合,大大减少元素比较次数
        set.retainAll(set2);
        System.out.println("set retainAll 耗时"+(System.currentTimeMillis()-time)+"--"+set.size());

        long time2=System.currentTimeMillis();
        //原理是去获取元素的下标indexOf,即在列表中依次遍历匹配目标元素直至找到相同的元素
        uidList.retainAll(openingRecordRoomUids);
        System.out.println("list retainAll 耗时"+(System.currentTimeMillis()-time2)+"--"+uidList.size());

    }
}


输出

set retainAll 耗时20--250
list retainAll 耗时577--250

标题:解决两个List求交集 retainAll()超级慢的方法
作者:不断努力的青春
地址:http://songaw.com/articles/2022/03/21/1647834771441.html