Bootstrap

布隆过滤器的原理及实现

一、布隆过滤器的工作原理

布隆过滤器本身是一个很长的二进制向量,既然是二进制的向量,那么显而易见的,存放的不是0,就是1。

新建一个16位的布隆过滤器,如图

在这里插入图片描述

有一个对象,我们通过

方式一计算他的hash值,得到hash = 2

方式二计算他的hash值,得到hash = 9

方式三计算他的hash值,得到hash = 5

通过三个方法计算得到三个数值,我们把这三个数值对应的布隆过滤器向量值改为1,表明该位置有值。

第二个对象,加入得到值1 6 3,就把1 6 3 改为1

对于布隆过滤器本身来说,并没有存储任何数据,只是计算该数据的位置,然后存储向量值

那么,如果需要判断某个数据是否存在于布隆过滤器,就只需要判断计算出来的所有向量值是否都为1即可。

但是,当存储的数据向量不断增多,就可能会出现,2 9 5 向量值都为1,但是实际上没有这个数据的情况,这样就导致了,布隆过滤器只能判断某个数据一定不存在,但是不能保证某个数据一定存在。

另外,因为一个向量位置可能被多个对象映射,所以,布隆过滤器无法删除数据

二、布隆过滤器的设计

如果向量长度太短,会导致误判率直线上升。

如果向量太长,会浪费大量内存。

如果计算次数过多,会占用计算资源,且很容易很快就把过滤器填满。

三、代码实现

POM文件依赖

 <dependency>  
  <groupId>com.google.guava</groupId>    
  <artifactId>guava</artifactId>  
  <version>25.1-jre</version></dependency>
</dependency>
 

测试代码

 public static void main(String... args){        
  /**         * 创建一个插入对象为一亿,误报率为0.01%的布隆过滤器         */      
   BloomFilter<CharSequence> bloomFilter =
   BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), 100000000, 0.0001);       
   bloomFilter.put("121");       
   bloomFilter.put("122");       
   bloomFilter.put("123");       
   System.out.println(bloomFilter.mightContain("121"));  
  }
 



 
;