日期:2014-05-20  浏览次数:20774 次

关于java剔除手机黑名单的算法,有没有更好的?
现在有两个集合,一个是号码集合,另外一个是黑名单集合,现在需要把号码集合中的黑名单剔除,目前用到的方式就是双循环,但是号码集合和黑名单集合都可能有几十万的号码,双循环的话速度太慢了,各位高人有没有什么号的方式剔除黑名单?

集合A:号码集合
集合B:黑名单集合
需要得到的结果:剔除集合B出现在集合A中的号码

------解决方案--------------------
如果是我我可能会使用以下两种方法。

1.我会将所有号码的集合放入一个Map中,key就是号码value是什么无所谓。然后循环黑名单,不断的到使用黑名单的值作为key去Map中查,查到就remove掉Map中相应的key.最后输出的Map就是去掉黑名单的号码集合了。

2.如果黑名单数量实在太大,试试Bloom过滤器。由于Map对于空间的利用率只有50%,数据量大的话空间浪费严重。使用Bloom过滤器对黑名单预先处理一下,再循环号码集合来不断的难证是否出现在黑名单中。

以下两个方法总有一个集合需要进行循环,那么为了加快速度可以对需要循环的集合进行拆分,比如每1000个为一组。每一组使用单独的线程来验证。
------解决方案--------------------
直接用HashSet就可以实现了
e.g
Java code

Set<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);

------解决方案--------------------
Collection的实现类都具有removeAll方法。
探讨
直接用HashSet就可以实现了
e.g

Java code


Set<String> a = new HashSet<String>();
a.add("1");
a.add("2");
a.add("3");
Set<String> b = new HashSet<String>();
b.add("1");
b.ad……

------解决方案--------------------
探讨
如果是我我可能会使用以下两种方法。

1.我会将所有号码的集合放入一个Map中,key就是号码value是什么无所谓。然后循环黑名单,不断的到使用黑名单的值作为key去Map中查,查到就remove掉Map中相应的key.最后输出的Map就是去掉黑名单的号码集合了。

2.如果黑名单数量实在太大,试试Bloom过滤器。由于Map对于空间的利用率只有50%,数据量大的话空间浪费严重。使用Bl……

------解决方案--------------------
如果放在Map里(注意相同好码的key值和value值是一样的),只需要循环完黑名单即可
Java code

        //如果集合在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);
        }

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


实验数据:10万黑名单数据,30万txt数据。。在自己的电脑上,到第5步完成用时没超过1分钟。。。服务器应该更快。。
------解决方案--------------------
如果不想使用数据库的话,,只能通过程序解决,考验应用程序性能,用etnet的也不错。。。还得看你的数据量,是很大。。还是超大。。。我的方法只是将开销转到数据库完成。。。
------解决方案--------------------
将压力给数据库,我个人呢其实不太喜欢。因为应用服务器可以方便的横向扩展,一台不行我上10台,每台服务器运行10个线程,每个线程处理N个号码。数据库就没那么方便的进行横向扩展了。