最近写爬虫需要降低内存的占用,现在用的是HashSet进行已爬URL的过滤,所以想到用布隆过滤器(Bloom Filter)来替换,从而减少内存的开销。因为HashSet内部是由HashMap处理的,HashMap则通过计算一个int型的hash值得出信息指纹,所以一个信息指纹占4字节,但是由于哈希的存储效率一般只有一半,所有说一条URL就需要8字节的信息指纹,而Bloom Filter 则只需要其1/2或更小的信息指纹就可以。

说一下Bloom Filter的工作原理:

假设有一条URL,那么就先建立32个二进制常量(这里个数还可以取其他值,但是误报率会不同,下面会有一张表格显示)。即4字节的向量,然后将这32个二进制位全部设置为0,对于这条URL,用8个不同的随机数产生8个信息指纹,再用一个随机数产生器把这8个信息指纹映射到1到32的8个自然数,并把这些位置置为1。

如果要检测某条URL是否在这个Bloom Filter中,我们仍然用上述8个随机数产生8个信息指纹,并将这8个指纹对应到布隆过滤器的8个二进制位,如果8位都为1,则说明这条URL在这个Bloom Filter中,否则只要有一位不为1,就说明不在。

Bloom Filter绝不会漏掉任何一个重复的URL,但可能会有误报情况,虽然这种可能性很小,上述说的误报概率只有千万分之一,可以通过建立一个小的名单,存储可能误判的URL,并进行比较。

Bloom Filter 误报率表:

最后是代码实现:

public class Test {public static void main(String[] args){BloomFilter b = new BloomFilter();b.addValue("www.baidu.com");b.addValue("www.sohu.com");System.out.println(b.contains("www.baidu.com"));System.out.println(b.contains("www.sina.com"));}
}class BloomFilter{private static final int BIT_SIZE = 2 << 28 ;//二进制向量的位数,相当于能存储1000万条url左右,误报率为千万分之一private static final int[] seeds = new int[]{3, 5, 7, 11, 13, 31, 37, 61};//用于生成信息指纹的8个随机数,最好选取质数private BitSet bits = new BitSet(BIT_SIZE);private Hash[] func = new Hash[seeds.length];//用于存储8个随机哈希值对象public BloomFilter(){for(int i = 0; i < seeds.length; i++){func[i] = new Hash(BIT_SIZE, seeds[i]);}}/*** 像过滤器中添加字符串*/public void addValue(String value)  {  //将字符串value哈希为8个或多个整数,然后在这些整数的bit上变为1if(value != null){for(Hash f : func) bits.set(f.hash(value), true); }}  /*** 判断字符串是否包含在布隆过滤器中*/public boolean contains(String value)  {  if(value == null) return false;  boolean ret = true;  //将要比较的字符串重新以上述方法计算hash值,再与布隆过滤器比对for(Hash f : func)ret = ret && bits.get(f.hash(value));  return ret;  }  /*** 随机哈希值对象*/public static class Hash{private int size;//二进制向量数组大小private int seed;//随机数种子public Hash(int cap, int seed){this.size = cap;this.seed = seed;}/*** 计算哈希值(也可以选用别的恰当的哈希函数)*/public int hash(String value){int result = 0;int len = value.length();for(int i = 0; i < len; i++){result = seed * result + value.charAt(i);}return (size - 1) & result;}}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

运行结果:

Java实现布隆过滤器(已爬URL过滤)相关推荐

  1. 基于ik分词器和布隆过滤器实现敏感词过滤

    文章目录 准备阶段 为何选用IK Analyzer 什么是布隆过滤器 开发过程 整合Ik 总结 <基于ik分词器和布隆过滤器实现敏感词过滤>首发 牧马人博客转发请加此提示 最近公司业务有个 ...

  2. Java实现布隆过滤器

    布隆过滤器 海量数据处理以及缓存穿透这两个场景让我认识了 布隆过滤器 ,我查阅了一些资料来了解它,但是很多现成资料并不满足我的需求,所以就决定自己总结一篇关于布隆过滤器的文章.希望通过这篇文章让更多人 ...

  3. Java开发 - 布隆过滤器初体验

    目录 前言 布隆过滤器 什么是布隆过滤器 布隆过滤器的作用 布隆过滤器原理 怎么设计布隆过滤器 布隆过滤器使用案例 安装布隆过滤器 添加依赖 添加配置 添加工具类 添加测试代码 简单测试 特别提醒​​ ...

  4. 布隆过滤器速度_5 分钟搞懂布隆过滤器,过滤亿级数据

    在程序的世界中,布隆过滤器是程序员的一把利器,利用它可以快速地解决项目中一些比较棘手的问题.如网页 URL 去重.垃圾邮件识别.大集合中重复元素的判断和缓存穿透等问题. 布隆过滤器(Bloom Fil ...

  5. 布隆过滤器实现 java

    布隆过滤器的作用是加快判定一个元素是否在集合中出现的方法.因为其主要是过滤掉了大部分元素间的精确匹配,故称为过滤器. 布隆过滤器 在日常生活工作,我们会经常遇到这的场景,从一个Excel里面检索一个信 ...

  6. 什么是布隆过滤器?如何使用?

    欢迎搜索 文章目录 一.布隆过滤器简介 二.布隆过滤器的结构 三.布隆过滤器应用 四.布隆过滤器的优缺点 五.布隆过滤器实战 六.总结 Redis缓存穿透可以通过布隆过滤器进行解决,那么什么是布隆过滤 ...

  7. 高并发下的redis击穿,你需要了解下布隆过滤器

    在高并发读的情况下缓存是不可少的.关于高并发缓存方面大小可以参考博主这篇文章 好了接下来进入正题: 缓存穿透 大家看下上方的这幅图,用户可能进行了一次条件错误的查询,这时候 redis 是不存在的,按 ...

  8. 布隆过滤器究竟是什么,这一篇给讲的明明白白的

    作者:jack_xu juejin.im/post/5e9c110151882573793e8940 不知道从什么时候开始,本来默默无闻的布隆过滤器一下子名声大燥,在面试中面试官问到怎么避免缓存穿透, ...

  9. 布隆过滤器原理及实践

    1 背景 现在有海量的数据,而这些数据的大小已经远远超出了服务器的内存,现在再来一条数据,如何快速高效判断这条数据在不在其中? 如果这些数据是存在数据库中的,考虑索引,分库分表:或者考虑其他目前主流的 ...

  10. Redis bitmap、hyperlog、布隆过滤器、RoaringBitmap原理应用场景与日活的统计的具体应用

    传统方案-mysql 缺点: 1.空间占用大 2.统计逻辑复杂,比如 统计最近 30 天用户的累计活跃天(每个用户在 30 天里有 N 天使用 app,N 为 1-30,然后将月活跃用户的 N 天加总 ...

最新文章

  1. 金融行业安全漏洞分析报告
  2. 多模态数据+知识图谱,这次你的疑难杂症有解了!
  3. 理解 Memory barrier(内存屏障)无锁环形队列
  4. 中国互金协会李东荣:力争在法定数字货币等领域深度参与国际标准规则制定
  5. 【报告分享】2020情趣用品线上消费趋势报告.pdf(附下载链接)
  6. 10打开没有反应_【专利】表面施胶剂的反应装置
  7. -------------初识----------动态规划。--------------------------------------------
  8. 中间环节越多,大家就越赚钱?
  9. 美国全国步枪协会遭 Grief 勒索软件攻击
  10. 新疆卫生系统计算机考试题库,2014新疆维吾尔自治区计算机等级考试试题 二级C试题最新考试试题库...
  11. 2021最新Java高频面试题,很适合大厂面试
  12. 命令行BASH的基本操作
  13. 威纶触摸屏485轮询通讯_威纶触摸屏Modbus TCP\RTU\ASCII通信视频教程
  14. 逆向分析中加解密算法常用工具
  15. 大家敏捷,才是真的敏捷——记敏捷培训
  16. iOS 权限设置判断和跳转 - 最全最详细
  17. 4天4夜渡劫成功,解决10月1项目上线遇到的一个Mysql大坑,导致项目无法正常访问
  18. 一个tomcat服务单独控制多个项目启停
  19. 无线网卡在服务器上不能启用,解决无线网卡突然不能启用的问题(事件ID4294)...
  20. 听说蚂蚁金服上市,但是实现财务自由的只是那些架构师?

热门文章

  1. DAG最小可重路径覆盖or最长反链的一种做法
  2. iOS开发之App上架流程(2017)
  3. 每一个写博客的程序猿,都应该被温柔对待
  4. 关于assert和de-assert的解释
  5. 哒哒的马蹄,由心而生的感情
  6. Android Butterknife框架 注解攻略
  7. JavaScript 实现模拟拖放
  8. 【转】OCI-22053: 溢出错误的原因和解决方法
  9. java Object类的公共方法
  10. 利用unittest+ddt进行接口测试(二):使用yaml文件管理测试数据