关于java剔除手机黑名单的算法,有没有更好的?

Mars.CN 2011-10-09 02:25:37
现在有两个集合,一个是号码集合,另外一个是黑名单集合,现在需要把号码集合中的黑名单剔除,目前用到的方式就是双循环,但是号码集合和黑名单集合都可能有几十万的号码,双循环的话速度太慢了,各位高人有没有什么号的方式剔除黑名单?

集合A:号码集合
集合B:黑名单集合
需要得到的结果:剔除集合B出现在集合A中的号码
...全文
358 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
etnet 2011-10-11
  • 打赏
  • 举报
回复
将压力给数据库,我个人呢其实不太喜欢。因为应用服务器可以方便的横向扩展,一台不行我上10台,每台服务器运行10个线程,每个线程处理N个号码。数据库就没那么方便的进行横向扩展了。
kouyiSC 2011-10-10
  • 打赏
  • 举报
回复
如果不想使用数据库的话,,只能通过程序解决,考验应用程序性能,用etnet的也不错。。。还得看你的数据量,是很大。。还是超大。。。我的方法只是将开销转到数据库完成。。。
Mars.CN 2011-10-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 kouyisc 的回复:]

前不久。我完成一个手机号码黑名单过滤功能。。。看了很多资料最终采用数据库临时表。将导入的一个几十万手机号码的txt文件进行黑名单过滤。
主要通过数据库,及临时表解决较快。数据库为sql2000
具体做法:
首先:写一个存储过程过滤黑名单【写一个过滤黑名单表的删除语句。进行黑名单过滤】,包括分页提取最后的数据,我的是每页100000条。
1. 导入txt将其加入HASHSET去掉重复。
……
[/Quote]

临时表的方式当时也考虑过,但是如果我做一个筛号软件的话,还需要在客户机上安装sqlserver,就太繁琐了,采用了etnet的第一种方法,效率挺高
kouyiSC 2011-10-09
  • 打赏
  • 举报
回复
前不久。我完成一个手机号码黑名单过滤功能。。。看了很多资料最终采用数据库临时表。将导入的一个几十万手机号码的txt文件进行黑名单过滤。
主要通过数据库,及临时表解决较快。数据库为sql2000
具体做法:
首先:写一个存储过程过滤黑名单【写一个过滤黑名单表的删除语句。进行黑名单过滤】,包括分页提取最后的数据,我的是每页100000条。
1. 导入txt将其加入HASHSET去掉重复。
2. 数据批量读入临时表
3. 调用存储过程进行过滤,循环分页自动提取。
4. 干净数据放入集合。
5. 清除临时表。
6. 下载一个没有黑名单的文件。


实验数据:10万黑名单数据,30万txt数据。。在自己的电脑上,到第5步完成用时没超过1分钟。。。服务器应该更快。。
Mars.CN 2011-10-09
  • 打赏
  • 举报
回复
etnet的第一种方式可行,removeAll方式貌似太慢了
liguangwen86 2011-10-09
  • 打赏
  • 举报
回复
如果放在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));
}

代码未测试,请见谅
duan 2011-10-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 etnet 的回复:]
如果是我我可能会使用以下两种方法。

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

2.如果黑名单数量实在太大,试试Bloom过滤器。由于Map对于空间的利用率只有50%,数据量大的话空间浪费严重。使用Bl……
[/Quote]
个人认为是个比较好的办法!
liuyuhua0066 2011-10-09
  • 打赏
  • 举报
回复
Collection的实现类都具有removeAll方法。
[Quote=引用 2 楼 wangxf_8341 的回复:]
直接用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……
[/Quote]
guoyang842 2011-10-09
  • 打赏
  • 举报
回复
楼主jj掉了?
淡定的峰哥 2011-10-09
  • 打赏
  • 举报
回复
直接用HashSet就可以实现了
e.g

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);
etnet 2011-10-09
  • 打赏
  • 举报
回复
如果是我我可能会使用以下两种方法。

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

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

以下两个方法总有一个集合需要进行循环,那么为了加快速度可以对需要循环的集合进行拆分,比如每1000个为一组。每一组使用单独的线程来验证。

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧