布隆过滤器详解:https://blog.csdn.net/Coco_Wditm/article/details/84635804;
它主要就是用于解决判断一个元素是否在一个集合中,但它的优势是只需要占用很小的内存空间以及有着高效的查询效率;
如图所示:
首先需要初始化一个二进制的数组,长度设为 L(图中为 8),同时初始值全为 0 。
当写入一个 A1=1000 的数据时,需要进行 H 次 hash 函数的运算(这里为 2 次);与 HashMap 有点类似,通过算出的 HashCode 与 L 取模后定位到 0、2 处,将该处的值设为 1。
A2=2000 也是同理计算后将 4、7 位置设为 1。
当有一个 B1=1000 需要判断是否存在时,也是做两次 Hash 运算,定位到 0、2 处,此时他们的值都为 1 ,所以认为 B1=1000 存在于集合中。
当有一个 B2=3000 时,也是同理。第一次 Hash 定位到 index=4 时,数组中的值为 1,所以再进行第二次 Hash 运算,结果定位到 index=5 的值为 0,所以认为 B2=3000 不存在于集合中。
整个的写入、查询的流程就是这样,汇总起来就是:
对写入的数据做 H 次 hash 运算定位到数组中的位置,同时将数据改为 1 。当有数据查询时也是同样的方式定位到数组中。
一旦其中的有一位为 0 则认为数据肯定不存在于集合,否则数据可能存在于集合中。
其实就是我说你没有 就一定没有,我说你有那你可能还不在呢。。
—————————————————————————————————————————————————————————————
上代码试试?
{ // 支持int string long 这个是string写法
public static void main(String[] args) {
long l = System.currentTimeMillis();
BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), 10000000000000l);
for (long i = 0; i < 10000000000000l; i++) {
bloomFilter.put(getStr());
}
if (bloomFilter.mightContain("asdgasd3")) {
System.out.println("存在!");
}
long s = System.currentTimeMillis();
System.out.println("执行时间-->"+(l-s));
}
private static String getStr(){
String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8);
return substring;
}
}
//这个是int写法 里面方法都是一样,均是调用这个;
{
public static void main(String[] args) {
long l = System.currentTimeMillis();
BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 10000000, 0.01);
for (int i = 0; i < 10000000; i++) {
bloomFilter.put(i);
}
if (bloomFilter.mightContain(3452346)) {
System.out.println("存在!");
}
long s = System.currentTimeMillis();
System.out.println("执行时间-->"+(l-s));
}
}
引用的是谷歌下的那个包;