布隆过滤器的概述和使用

news2024/12/23 20:42:00

1 布隆过滤器概述

1.1 概述

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是由一个很长的二进制向量(数组)和一系列随机映射函数(hash函数)组成,它不存放数据的明细内容,仅仅标识一个数据是否存在的信息。布隆过滤器可以用于检索一个元素在一个数组或集合中是否存在。

它的优点是空间效率和查询时间都比一般的算法要好,缺点是有一定的误判率(hash冲突导致的)和数据删除困难。

1.2 基本原理

布隆过滤器的基本原理如下所述:

  • 数据存储到布隆过滤器:创建一个指定长度的数组,数组元素的初始值均为0。通过一个或多个Hash函数将数据映射成该数组中的一个点或者多个点,并将这些点位的元素值设置为非0。
  • 判断某个数据在布隆过滤器中是否存在:通过hash函数计算某个数据在数组上对应的所有点是不是都非0。如果都非0,则该数据可能存在;如果有一个为0,则该数据一定不存在。

举例:当向过滤器存入 “Good” 时,假设过滤器的 3 个哈希函数输出 1、3、6,则把数组相应位置的元素置为 1。

2 布隆过滤器的使用

下面是对布隆过滤器的简单使用。采用的过滤器是guava中对布隆过滤器的实现。

2.1 依赖

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

2.2 主要的方法

创建布隆过滤器:BloomFilter#create
往过滤器中插入数据: BloomFilter#put
判断数据在过滤器中是否可能存在:BloomFilter#mightContain

2.3 使用示例

import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.util.List;


public class BloomFilterDemo {
    public static void main(String[] args) {
        // 过滤器中存储数据
        int total = 1000000;
        List<String> baseList = Lists.newArrayList();
        for (int i = 0; i < total; i++) {
            baseList.add("" + i);
        }

        // 待匹配的数据
        // 布隆过滤器应该匹配到的数据量:1000000
        List<String> inputList = Lists.newArrayList();
        for (int i = 0; i < total + 10000; i++) {
            inputList.add("" + i);
        }

        // (1)条件:expectedInsertions:100w,fpp:3%
        // 结果:numBits:约729w(数组size:约729w/64),numHashFunctions:5
        System.out.println("expectedInsertions:100w,fpp:3%,匹配到的数量 " + bloomFilterCheck(baseList, inputList, baseList.size(), 0.03));

        // (2)条件:expectedInsertions:100w,fpp:0.0001%
        // 结果:numBits:约2875w(数组size:约2875w/64),numHashFunctions:20
        System.out.println("expectedInsertions:100w,fpp:0.0001%,匹配到的数量 " + bloomFilterCheck(baseList, inputList, baseList.size(), 0.000001));

        // (3)条件:expectedInsertions:1000w,fpp:3%
        // 结果:numBits:约7298w(数组size:约7298w/64),numHashFunctions:5
        System.out.println("expectedInsertions:1000w,fpp:3%,匹配到的数量 " + bloomFilterCheck(baseList, inputList, baseList.size() * 10, 0.03));
    }

    /**
     * 布隆过滤器
     *
     * @param baseList           过滤器中存储的数据
     * @param inputList          待匹配的数据
     * @param expectedInsertions 可能插入到过滤器中的总数据量
     * @param fpp                误判率
     * @return 在布隆过滤器中可能存在数据量
     */
    private static int bloomFilterCheck(List<String> baseList, List<String> inputList, int expectedInsertions, double fpp) {
		// 创建布隆过滤器
        BloomFilter<String> bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), expectedInsertions, fpp);
        // 初始化数据到过滤器中
        for (String string : baseList) {
            // 在对应索引位置存储非0的hash值
            bf.put(string);
        }

        // 判断值是否存在过滤器中
        int count = 0;
        for (String string : inputList) {
            if (bf.mightContain(string)) {
                count++;
            }
        }

        return count;
    }

}

运行结果

expectedInsertions:100w,fpp:3%,匹配到的数量 1000309
expectedInsertions:100w,fpp:0.0001%,匹配到的数量 1000000
expectedInsertions:1000w,fpp:3%,匹配到的数量 1000000

结论:

expectedInsertions 和 fpp 决定了布隆过滤器的大小(数组大小),fpp 决定了哈希函数的个数。而布隆过滤器的大小和哈希函数的个数共同决定了布隆过滤器的误判率。

因此使用此过滤器时,需要根据存储到过滤器中的数据量,通过测试后,设置相对合理的expectedInsertions 和 fpp值,从而较小误判率。

3 参考文献

(1) 什么是布隆过滤器?如何使用?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1428961.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言中的指针详解

大家好&#xff0c;今天给大家介绍C语言中的指针详解&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 **指针是C语言中的一个重要概念&#xff0c;它提供了一种直接访问内存地址…

【学员分享-考试心得】国产数据库潜力无限,云贝教育OBCP认证培训帮您解难题

近年来&#xff0c;随着国产化转型的推进&#xff0c;国外数据库的岗位需求逐渐减少&#xff0c;让许多IT从业者倍感压力。在这种情况下&#xff0c;了解国产数据库成为了求职市场上的竞争力。云贝老师们将聚焦于OceanBase、PostgreSQL、TDSQL等IT培训&#xff0c;探讨其对国产…

LED点阵屏(基于51单片机)

师从江科大 LED点阵屏 LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。 LED点阵屏分类 按颜色&#xff1a;单色、双色、全彩 按像素&#xff1a;8*8、16*16等&#xff08;大规模的LED点阵通常由很多个…

SpringBoot实战2

目录 1.如何返回两个类型的数据&#xff1f;User和Booth 2.如何使用MyBatis遍历一个数组进行查询&#xff1f; 3.前端要的数据太多太杂&#xff0c;我们拼接多个List&#xff0c;前端找数据困难&#xff0c;浪费时间。因此我们进行三表联表查询。 1.首先创建一个vo包&#x…

【数据结构】双向链表 超详细 (含:何时用一级指针或二级指针;指针域的指针是否要释放)

目录 一、简介 二. 双链表的实现 1.准备工作及其注意事项 1.1 先创建三个文件 1.2 注意事项&#xff1a;帮助高效记忆 1.3 关于什么时候 用 一级指针接收&#xff0c;什么时候用 二级指针接收&#xff1f; 1.4 释放节点时&#xff0c;要将节点地址 置为NULL&#xff0…

FANUC机器人开机时无法进入系统,示教器黑屏故障处理总结

FANUC机器人开机时无法进入系统&#xff0c;示教器黑屏故障处理总结 故障描述&#xff1a; FANUC机器人开机时&#xff0c;示教器在初始化时显示&#xff1a;EMAC initial call failed&#xff08;示教器上电时会进入boot画面&#xff0c;左上角会出现一些白色的英文提示&#…

项目安全-----加密算法实现

目录 对称加密算法 AES &#xff08;ECB模式&#xff09; AES(CBC 模式)。 非对称加密 对称加密算法 对称加密算法&#xff0c;是使用相同的密钥进行加密和解密。使用对称加密算法来加密双方的通信的话&#xff0c;双方需要先约定一个密钥&#xff0c;加密方才能加密&#…

openGauss学习笔记-212 openGauss 数据库运维-日志参考

文章目录 openGauss学习笔记-212 openGauss 数据库运维-日志参考212.1 日志类型简介212.2 系统日志212.3 操作日志212.4 审计日志212.5 WAL日志212.6 性能日志 openGauss学习笔记-212 openGauss 数据库运维-日志参考 212.1 日志类型简介 在数据库运行过程中&#xff0c;会出现…

Java面试——计网篇

一、基础篇 1、 TCP/IP 网络模型 对于同一台设备上的进程间通信&#xff0c;有很多种方式&#xff0c;比如有管道、消息队列、共享内存、信号等方式&#xff0c;而对于不同设备上的进程间通信&#xff0c;就需要网络通信&#xff0c;而设备是多样性的&#xff0c;所以要兼容多…

RDBMS-MySQL高级

数据操作语句&#xff08;DML&#xff09;多表/关联查询Mysql中的函数事务执行流程数据库的备份与还原数据库表设计三范式 一、数据操作语句&#xff08;DML&#xff09; 插入数据 语法&#xff1a; 1.1插入&#xff08;insert [into]&#xff09;或添加一条数据 -- 指定列…

excel统计分析——卡方独立性检验(下)

参考资料&#xff1a;生物统计学 书接上文&#xff1a;https://blog.csdn.net/maizeman126/article/details/135893731 2、配对列联表 配对设计的数据&#xff0c;进行列联表检验时&#xff0c;采用McNemar-Bowker检验法进行检验。检验统计量为&#xff1a; 自由度dfk(k-1)/2…

CSS要点总结

一、CSS 快速入门 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>css 快速入门</title><!-- 解读1. 在 head 标签内&#xff0c;出现了 <style type"text/css"></style…

Spring Framework(6.x)源码编译与源码阅读入门

目录 一、Spring Framework 源码获取问题 1.1 Spring Framework 官网 1.2 Spring Framework 源码地址 1.3 关于访问不了GitHub 官网的解决方案 1.3.1 修改本地hosts文件 1.3.2 GitHub520 1.3.3 Gitee 导入 二、Spring Framework 源码编译 2.1 环境说明 2.1.1 JDK版本 …

代码随想录算法训练营29期|day38 任务以及具体安排

第九章 动态规划part01 509. 斐波那契数 //非压缩状态的版本 class Solution {public int fib(int n) {if (n < 1) return n; int[] dp new int[n 1];dp[0] 0;dp[1] 1;for (int index 2; index < n; index){dp[index] dp[index - 1] dp[index - 2];}r…

【AI数字人-论文】Geneface论文

文章目录 前言pipelineaudio-to-motionMotion domain adaptation可视化 Motion-to-imageHead-NeRFTorso-NeRF 结果对比 前言 语音驱动的说话人视频合成旨在根据一段输入的语音&#xff0c;合成对应的目标人脸说话视频。高质量的说话人视频需要满足两个目标&#xff1a; &#…

【无标题】Vue项目中你是如何解决跨域的呢?

文章目录 一、跨域是什么二、如何解决CORSProxy 一、跨域是什么 跨域本质是浏览器基于同源策略的一种安全手段 同源策略&#xff08;Sameoriginpolicy&#xff09;&#xff0c;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能 所谓同源&#xff08;即指在同一个域…

Cmake语法学习3:语法

1.双引号 1.1 命令参数 1&#xff09;介绍 命令中多个参数之间使用空格进行分隔&#xff0c;而 cmake 会将双引号引起来的内容作为一个整体&#xff0c;当它当成一个参数&#xff0c;假如你的参数中有空格&#xff08;空格是参数的一部分&#xff09;&#xff0c;那么就可以使…

智慧商城(continue)

文章目录 1.静态页面结构准备和动态渲染2.搜索 - 历史记录管理1. 写好基础静态页面,可以先往里面加一点假数据2. 上面基本的渲染直接利用history渲染就可以了3. 搜索历史基本渲染结束了,开始点击搜索添加历史4. vant内用v-model" ",可以快速拿到搜索框的值5. 往历史记…

Vue3.0(一):Vue的引入-options api-模板语法

Vue的引入方式 CDN方式进行引入 将以下 script标签引入即可 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script><!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><met…