布隆过滤器

布隆过滤器是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。主要用于判断一个元素是否在一个集合中。

通常我们会遇到很多要判断一个元素是否在某个集合中的业务场景,一般想到的是将集合中所有元素保存起来,然后通过比较确定。链表、树、散列表(又叫哈希表,Hash table)等等数据结构都是这种思路。但是随着集合中元素的增加,我们需要的存储空间也会呈现线性增长,最终达到瓶颈。同时检索速度也越来越慢,上述三种结构的检索时间复杂度分别为O ( n ) O(n)O(n),O ( l o g n ) O(logn)O(logn),O ( 1 ) O(1)O(1)。

这个时候,布隆过滤器(Bloom Filter)就应运而生。

误判率

布隆过滤器的误判是指多个输入经过哈希之后在相同的bit位置1了,这样就无法判断究竟是哪个输入产生的,因此误判的根源在于相同的 bit 位被多次映射且置 1。

这种情况也造成了布隆过滤器的删除问题,因为布隆过滤器的每一个 bit 并不是独占的,很有可能多个元素共享了某一位。如果我们直接删除这一位的话,会影响其他的元素。(比如上图中的第 3 位)

优点

相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数 O ( K ) O(K)O(K),另外,散列函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。

布隆过滤器可以表示全集,其它任何数据结构都不能;

缺点

但是布隆过滤器的缺点和优点一样明显。误算率是其中之一。随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣。

另外,一般情况下不能从布隆过滤器中删除元素。我们很容易想到把位数组变成整数数组,每插入一个元素相应的计数器加 1, 这样删除元素时将计数器减掉就可以了。然而要保证安全地删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面。这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。

在降低误算率方面,有不少工作,使得出现了很多布隆过滤器的变种。

在程序的世界中,布隆过滤器是程序员的一把利器,利用它可以快速地解决项目中一些比较棘手的问题。

如网页 URL 去重、垃圾邮件识别、大集合中重复元素的判断和缓存穿透等问题。

布隆过滤器的典型应用有:

代码实现

import java.util.BitSet;public class MyBloomFilter {/*** 位数组的大小*/private static final int DEFAULT_SIZE = 2 << 24;/*** 通过这个数组可以创建 6 个不同的哈希函数*/private static final int[] SEEDS = new int[]{3, 13, 46, 71, 91, 134};/*** 位数组。数组中的元素只能是 0 或者 1*/private BitSet bits = new BitSet(DEFAULT_SIZE);/*** 存放包含 hash 函数的类的数组*/private SimpleHash[] func = new SimpleHash[SEEDS.length];/*** 初始化多个包含 hash 函数的类的数组,每个类中的 hash 函数都不一样*/public MyBloomFilter() {// 初始化多个不同的 Hash 函数for (int i = 0; i < SEEDS.length; i++) {func[i] = new SimpleHash(DEFAULT_SIZE, SEEDS[i]);}}/*** 添加元素到位数组*/public void add(Object value) {for (SimpleHash f : func) {bits.set(f.hash(value), true);}}/*** 判断指定元素是否存在于位数组*/public boolean contains(Object value) {boolean ret = true;for (SimpleHash f : func) {ret = ret && bits.get(f.hash(value));}return ret;}/*** 静态内部类。用于 hash 操作!*/public static class SimpleHash {private int cap;private int seed;public SimpleHash(int cap, int seed) {this.cap = cap;this.seed = seed;}/*** 计算 hash 值*/public int hash(Object value) {int h;return (value == null) ? 0 : Math.abs(seed * (cap - 1) & ((h = value.hashCode()) ^ (h >>> 16)));}}
}
class too{public static void main(String[] args) {String value1 = "https://javaguide.cn/";String value2 = "https://github.com/Snailclimb";MyBloomFilter filter = new MyBloomFilter();System.out.println(filter.contains(value1));System.out.println(filter.contains(value2));filter.add(value1);filter.add(value2);System.out.println(filter.contains(value1));System.out.println(filter.contains(value2));}
}

测试结果

布隆过滤器简单实现添加和判断功能相关推荐

  1. 判断数组中某个元素除自身外是否和其他数据不同_布隆过滤器,我也是个处理过 10 亿数据的人...

    ❝ 文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 什么是 BloomFilter 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的.它实际上是 ...

  2. Redis 高级主题之布隆过滤器(BloomFilter)

    最近计划准备整理几篇关于Reids高级主题的博文,本文整理的是关于布隆过滤器在Redis中如何应用,先来一张思维导图浏览全文. 1. 认识BloomFilter 1.1 原理 布隆过滤器,英文叫Blo ...

  3. filter过滤器_不了解布隆过滤器?一文给你整的明明白白!

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

  4. 深入详解Redis布隆过滤器

    前面学习HyperLogLog数据类型来进行估算,还是非常有意义的,能解决很多精度要求不高的统计问题. 但是对于某一个值是否存在于HyperLogLog结构里面,就变现的无能为力,因为它只提供了 pf ...

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

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

  6. 详解各种布隆过滤器原理及使用场景

    文章目录 1.什么是布隆过滤器? 2.布隆过滤器的原理介绍 3.布隆过滤器使用场景 4.通过 Java 编程手动实现布隆过滤器 5.利用Google开源的 Guava中自带的布隆过滤器 6.Redis ...

  7. 解决Redis缓存穿透之布隆过滤器详解

    文章目录 1. 什么是Bloom Filter(布隆过滤器) 1.1 布隆过滤器优点 1.2 布隆过滤器缺点 1.3 布隆过滤器使用场景 1.4 布隆过滤器检索过程 1.5 布隆过滤器的算法描述 2. ...

  8. JSD-2204-续Docker命令-布隆过滤器的测试-秒杀业务完善-ELK-配置中心-Day18

    1.续 Docker命令 1.1ps命令 docker ps 可以查看当前docker中运行的所有容器的状态 ps命令中常见的选项如下: -a:显示所有容器,如果不加只显示正在启动运行的容器,停止的不 ...

  9. 布隆过滤器速度_布隆过滤器,你也可以处理十几亿的大数据

    文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 什么是 BloomFilter 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的.它实际上是一个 ...

最新文章

  1. php多个 r n如何过滤,php怎么去掉r n
  2. java三大范_Java深度学习系列——数据库的三大范式
  3. 厚积薄发,拥抱 .NET 2016
  4. Git 版本管理工具命令速查
  5. 5款神器级别Github 的Chrome插件
  6. 法国电信:5G加速数字化落地 物联网是首座金矿
  7. [转载] 杜拉拉升职记——34 设定工作目标要符合“SMART”原则
  8. phpstudy 线上添加域名
  9. 使用JFlash往Nordic nRF系列芯片烧写程序
  10. newifimini出厂固件_newifi 新路由 mini用哪个Pandora固件
  11. Cisco路由器密码设置
  12. 运维守护神——数十万线上机器的守护【门神】
  13. HTML5期末大作业:旅游网站设计——中国风的旅游网站(9页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码...
  14. Linux下使用aMsn详解(转)
  15. 计算机考研与就业的利弊分析,考研和就业怎么选择 考研和就业的利弊分析
  16. c语言指针面试经典选择题及答案,C语言指针经典练习题-及答案
  17. 树-生成树-最小生成树
  18. php access 教程 pdf,Access 2007 以PDF 格式保存文件
  19. IoT黑板报:英特尔公布LTE通讯模组XMM 7560
  20. useEffect 清理副作用

热门文章

  1. TFT-LCD屏幕触摸校准
  2. Codeforces Round #637 (Div. 2) - Thanks, Ivan Belonogov! C. Nastya and Strange Generator
  3. 使用Arduino Leonardo开发板制作操纵杆游戏控制器
  4. matlab创建圆点标定板,(halcon实例)一种蜂窝圆点标定板校准CCD并测量的例子
  5. 关于网络安全必读的10本书
  6. qos 流控功能_探讨一下QoS存在的意义以及使用场景
  7. 良好的分布式cahce系统中,一致性hash算法需要满足什么?
  8. c语言指针读书笔记,《C与指针》读书笔记九
  9. hadoop报错总结01_李孟_新浪博客
  10. 关于导入图片的函数loadimage在VS2017种报错没有与参数列表匹配重载函数的字符集报错问题