Java——布隆过滤器

news/2024/11/30 2:48:24/

在上一篇博客中讲到位图是用来判定一个正整数是否存在的。对于一个负数,我们可以统一规定让他们加上一个数,变成正数,然后用位图的方式存储。但是对于字符串,我们就没办法存储了。因此发明了布隆过滤器

概念

对于网络上很多需要判定是否存在的字符串信息(例如垃圾邮件的地址),我们没有办法使用位图或者其他数据结构来高效的查找。因此发明了布隆过滤器

布隆过滤器是将一个字符串通过多个哈希函数,得到不容的正数,然后将这些正数插入到位图中。由于其他的字符串也可能哈希出一样的值,多个字符串就可能哈希到重合的位置上。因此布隆过滤器的查找并不是准确的,而是得出——这个字符串一定不存在,或者这个字符串可能存在

当一个字符串哈希成不同的值后,分别判断这些值是否在位图上存在,如果有一个不存在,则可以判断这个字符串一定不存在(如果存在,那么在存储时这些值都应该存在)。而如果这些值都存在,这个字符串也不能说是百分百存在的,因为可能这些值都是别的字符串哈希后存储的

可以看到,布隆过滤器在效率和空间上都是十分优秀的,并且,我们存储的位图并不包含字符串的相关信息,因此也认为是一种安全的存储方式

MyBloomFilter

SimpleHash

先创建一个自己的哈希函数

这里我们需要传输当前的容量和随机的种子,不同的种子就会产生不同的哈希值

然后定义一个hash方法,在之后,我们将调用这个hash方法,来将字符串转换为不同的正数

这里的哈希值计算和源码的形成方法类似

class SimpleHash {public int capacity;// 当前容量public int seed; //随机种子public SimpleHash(int capacity, int seed){this.capacity = capacity;this.seed = seed;}/*** 根据不同的seed,创建不同的哈希函数* @param key* @return*/int hash(String key){int h;return (key == null) ? 0 : (seed * (capacity - 1)) & ((h = key.hashCode()) ^ (h >>> 16));}
}

定义

定义SimpleHash的默认容量,SimpleHash中用到的所有种子,然后在初始化MyBloomFilter的时候,创建所有的SimpleHash,给他们赋不同的种子

public final int DEFAULT_SIZE = 1 << 20;
public BitSet bitSet;
public int usedSize;
public static final int[] seeds = {5,7,11,13,27,33};
public SimpleHash[] simpleHashes;public MyBloomFilter(){bitSet = new BitSet(DEFAULT_SIZE);simpleHashes = new SimpleHash[seeds.length];for (int i = 0; i < simpleHashes.length; i++) {simpleHashes[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);}
}

add方法

遍历每一个SimpleHash,调用其中的hash方法,传入字符串得到不同的index,然后用位图将这些index设置为true,最后让usedSize++

/*** 添加val到布隆过滤器* @param val*/
public void add(String val){// 用X个不同的哈希函数处理数据//将处理后的数据存储在位图中for (SimpleHash simpleHash : simpleHashes) {int index = simpleHash.hash(val);bitSet.set(index);}usedSize++;
}

contains方法

还是调用所有的SimpleHash中的hash方法,得到所有的index,然后判断这些index在位图中是否存在,如果不存在,说明这个字符串一定不存在,如果存在,只能说明这个字符串可能存在

/*** 判断val是否存在* @param val* @return 可能存在(返回true) / 一定不存在(返回false)*/
public boolean contains(String val){for (SimpleHash simpleHash : simpleHashes) {int index = simpleHash.hash(val);if(!bitSet.get(index)){return false;}}return true;
}

test测试

public class test {public static void main(String[] args) {MyBloomFilter myBloomFilter = new MyBloomFilter();myBloomFilter.add("hello");myBloomFilter.add("hello2");myBloomFilter.add("hi");myBloomFilter.add("world");myBloomFilter.add("xiao");System.out.println(myBloomFilter.contains("hello"));System.out.println(myBloomFilter.contains("hello1"));System.out.println(myBloomFilter.contains("hahahaha"));}
}

在这里插入图片描述
可以看到我们得到的结果是正确的

外部引用

谷歌也有布隆过滤器的实现,可以用maven引用

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>19.0</version>
</dependency>

可以分别传入自己要插入的数据的个数和期待的误判率是多高

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;public class Test {private static int size = 1000000;//预计要插入多少数据private static double fpp = 0.01;//期望的误判率private static BloomFilter<Integer> bloomFilter= BloomFilter.create(Funnels.integerFunnel(), size, fpp);public static void main(String[] args) {//插入数据for (int i = 0; i < 1000000; i++) {bloomFilter.put(i);}int count = 0;for (int i = 1000000; i < 2000000; i++) {if (bloomFilter.mightContain(i)) {count++;System.out.println(i + "误判了");}}System.out.println("总共的误判数:" + count);}}

最终得到的误判个数是接近误判率的


http://www.ppmy.cn/news/3938.html

相关文章

[附源码]Python计算机毕业设计高校学生管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等…

win7 nvm-window 安装图解

序&#xff1a; 1、博主不是没试过装nvmw&#xff0c;但是npm install nvmw下来&#xff0c;发现切换不了的&#xff0c;就算独立下载nvmw下来配置也试过了&#xff0c;也是不行&#xff0c;最重要的一点nvmw已经停更了&#xff01;&#xff01;&#xff01;&#xff01; 2、删…

java的垃圾回收浅谈

目录 并发标记问题 三色算法问题 浮动垃圾问题 漏标问题 cms的解决方式 g1的解决方式 跨代(区)引用 CMS垃圾回收日志 G1垃圾回收日志 垃圾回收过程其实都包含两步&#xff1a;标记回收。 标记算法&#xff1a; 引用计数&#xff1a;每个对象都有一个计数器&#xff…

所谓工作能力强,其实就这五点

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; #mermaid-svg-YapmQUqJ0V32EFv6 {font-family:"trebuchet ms",ve…

【大数据技术Hadoop+Spark】MapReduce之单词计数和倒排索引实战(附源码和数据集 超详细)

源码和数据集请点赞关注收藏后评论区留言私信~~~ 一、统计单词出现次数 单词计数是最简单也是最能体现MapReduce思想的程序之一&#xff0c;可以称为MapReduce版“Hello World。其主要功能是统计一系列文本文件中每个单词出现的次数 程序解析 首先MapReduce将文件拆分成spli…

计算机毕设Python+Vue校园失物招领平台(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

十大编程语言黑客向,学会一个不怕没工作,全部学会随便秀操作

首先文章并不是鼓励大家去成为黑客&#xff0c;毕竟这个用在错误的地方&#xff0c;您最终可能需要尝试牢狱之灾。因为有很多的编程语言我也不是很懂&#xff0c;所以借鉴了一些专业人员的看法。当然他们不是黑客。然后下面给大家大概的介绍下其中十个吧。下期为您介绍剩下的几…

使用transformers框架导入bert模型提取中文词向量

导言 在笔者的上一篇文章大白话讲懂word2vec原理和如何使用中提到了如何将词语转变成计算机能够识别的语言&#xff0c;即将文本数据转换成计算机能够运算的数字或者向量这个概念&#xff0c;并详细阐述了word2vec这个模型的原理&#xff0c;如何在gensim框架下使用word2vec将…