布隆过滤器

1.简介:
布隆过滤器的主要是由一个很长的二进制向量和若干个(k个)散列映射函数组成。因为每个元数据的存储信息值固定,而且总的二进制向量固定。所以在内存占用和查询时间上都远远超过一般的算法。
当然存在一定的不准确率(可以控制)和不容易删除样本数据。

算法:
1. 首先需要k个hash函数,每个函数可以把key散列成为1个整数
2. 初始化时,需要一个长度为n比特的数组,每个比特位初始化为0
3. 某个key加入集合时,用k个hash函数计算出k个散列值,并把数组中对应的比特位置为1
4. 判断某个key是否在集合时,用k个hash函数计算出k个散列值,并查询数组中对应的比特位,如果所有的比特位都是1,认为在集合中。

注:

(1)随着存入的元素数量增加,误算率随之增加。但是如果元素数量太少,则使用散列表足矣。
(2)一般情况下不能从布隆过滤器中删除元素。我们很容易想到把位列阵变成整数数组,每插入一个元素相应的计数器加1, 这样删除元素时将计数器减掉就可以了。
然而要保证安全的删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面. 这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。
(3)在降低误算率方面,有不少工作,使得出现了很多布隆过滤器的变种。

 

2.使用
public class Test02 {

  private static Integer size = 10000;
  private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(),size);


  public static void main(String[] args){

    System.out.println("=============布隆过滤器");
    for(int i=0;i<size;i++){
    bloomFilter.put(i);
  }

  Integer num = 9999;
  if(bloomFilter.mightContain(num)){
    System.out.println("数字" + num + "在当前过滤器中");
  }

  List<Integer> list = new ArrayList<Integer>(1000);
  // 故意取10000个不在过滤器里的值,看看有多少个会被认为在过滤器里
  for (int i = size + 10000; i < size + 20000; i++) {
    if (bloomFilter.mightContain(i)) {
      list.add(i);
    }
  }
  System.out.println("误判的数量:" + list.size());

  }
}

posted @ 2019-10-31 15:37  smj1990  阅读(199)  评论(0编辑  收藏  举报