布隆过滤器(Bloom Filter)是一种比较巧妙的数据结构, 他的功能就是判断一个元素是否在一个集合中, 相比于List, Hash等数据结构,它使用的空间很小, 原理就是通过N个hash函数,映射到一个位图上,将指定位置的位图元素设置为1,因为它不存储原始数据,再加上位图长度没有办法扩展,所以有一定的误差, 这个误差用大白话来说就是: 如果布隆过滤器告诉你,一个元素不存在于集合中,那它一定不存在,如果告诉你一个元素存在于一个集合中,那它有可能存在,也有可能不存在, 这个误差 叫做 假阳性(FPP), 机器学习中二分类的混淆矩阵就有这个的介绍。
这里直接使用guava中自带的
package org.example; import com.google.common.hash.BloomFilter; import com.google.common.hash.Funnels; import java.nio.charset.Charset; public class App { public static void main(String[] args) { BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 5, 0.01); filter.put("a"); System.out.println("contain:" + filter.mightContain("a")); System.out.println("FPP" + filter.expectedFpp()); System.out.println("-------------------------------------------------"); filter.put("b"); filter.put("c"); filter.put("d"); System.out.println("contain:" + filter.mightContain("d")); System.out.println("FPP" + filter.expectedFpp()); System.out.println("-------------------------------------------------"); filter.put("e"); System.out.println("contain:" + filter.mightContain("e")); System.out.println("FPP" + filter.expectedFpp()); System.out.println("-------------------------------------------------"); } }
Bloom Filter有如下几个扩展:
Counting filters: 将原来的1个bit扩展为N个bit,可以实现元素的删除,代价就是整体的扩展也扩大了N倍
Counting filters: 将原来的1个bit扩展为N个bit,可以实现元素的删除,代价就是整体的扩展也扩大了N倍
Compressed Bloom Filter
redis中的Bloom Filter通过下面三个命令控制
bf.reserve 创建一个Bloom Filter
bf.add/bf.madd 添加元素到Bloom Filter
bf.exists 判断元素是否在Bloom Filter中