现在有两个集合,一个是号码集合,另外一个是黑名单集合,现在需要把号码集合中的黑名单剔除,目前用到的方式就是双循环,但是号码集合和黑名单集合都可能有几十万的号码,双循环的话速度太慢了,各位高人有没有什么号的方式剔除黑名单?集合A:号码集合
集合B:黑名单集合
需要得到的结果:剔除集合B出现在集合A中的号码

解决方案 »

  1.   

    如果是我我可能会使用以下两种方法。1.我会将所有号码的集合放入一个Map中,key就是号码value是什么无所谓。然后循环黑名单,不断的到使用黑名单的值作为key去Map中查,查到就remove掉Map中相应的key.最后输出的Map就是去掉黑名单的号码集合了。2.如果黑名单数量实在太大,试试Bloom过滤器。由于Map对于空间的利用率只有50%,数据量大的话空间浪费严重。使用Bloom过滤器对黑名单预先处理一下,再循环号码集合来不断的难证是否出现在黑名单中。以下两个方法总有一个集合需要进行循环,那么为了加快速度可以对需要循环的集合进行拆分,比如每1000个为一组。每一组使用单独的线程来验证。
      

  2.   

    直接用HashSet就可以实现了
    e.gSet<String> a = new HashSet<String>();
    a.add("1");
    a.add("2");
    a.add("3");
    Set<String> b = new HashSet<String>();
    b.add("1");
    b.add("3");
    a.removeAll(b);
    System.out.println(a);
      

  3.   

    Collection的实现类都具有removeAll方法。
      

  4.   

    如果放在Map里(注意相同好码的key值和value值是一样的),只需要循环完黑名单即可 //如果集合在Map里
    Map map1 = new HashMap<String, String>();
    map1.put("aaaa", "aaaa");
    map1.put("cccc", "cccc");
    map1.put("dddd", "dddd");
    Map<String, String> map2 = new HashMap<String, String>();
    map2.put("aaaa", "aaaa");
    map2.put("cccc2", "cccc2");
    map2.put("dddd2", "dddd2");

    Set entries = map2.entrySet();
    Iterator iterator = entries.iterator();
    //循环完黑名单集合即可
    while(iterator.hasNext()) 
    {
    Entry entry =(Entry)iterator.next();
    Object key = entry.getKey();
    map1.remove(key);
    }
    如果放在list里,也是只要循环完黑名单即可(号码集合不重复可以用) //如果集合在list里
    List<String> list1 = new ArrayList<String>();
    list1.add("222");
    list1.add("aaaaaaa");
    list1.add("eee");

    List<String> list2 = new ArrayList<String>();
    list2.add("aaaaaaa1");
    list2.add("eee1");
    list2.add("222");
    //循环完黑名单集合即可
    for(int i=0;i<list2.size();i++)
    {
    list1.remove(list2.get(i));
    }代码未测试,请见谅
      

  5.   

    etnet的第一种方式可行,removeAll方式貌似太慢了
      

  6.   

    前不久。我完成一个手机号码黑名单过滤功能看了很多资料最终采用数据库临时表。将导入的一个几十万手机号码的txt文件进行黑名单过滤。
    主要通过数据库,及临时表解决较快。数据库为sql2000
    具体做法: 
    首先:写一个存储过程过滤黑名单【写一个过滤黑名单表的删除语句。进行黑名单过滤】,包括分页提取最后的数据,我的是每页100000条。
    1. 导入txt将其加入HASHSET去掉重复。
    2. 数据批量读入临时表
    3. 调用存储过程进行过滤,循环分页自动提取。
    4. 干净数据放入集合。
    5. 清除临时表。
    6. 下载一个没有黑名单的文件。
    实验数据:10万黑名单数据,30万txt数据。。在自己的电脑上,到第5步完成用时没超过1分钟服务器应该更快。。
      

  7.   


    临时表的方式当时也考虑过,但是如果我做一个筛号软件的话,还需要在客户机上安装sqlserver,就太繁琐了,采用了etnet的第一种方法,效率挺高
      

  8.   

    如果不想使用数据库的话,,只能通过程序解决,考验应用程序性能,用etnet的也不错还得看你的数据量,是很大。。还是超大我的方法只是将开销转到数据库完成