Java——布隆过滤器

news2025/1/18 4:38:57

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

概念

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

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

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

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

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.coloradmin.cn/o/93541.html

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

相关文章

计算机毕设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…

【从零开始学习深度学习】26.卷积神经网络之AlexNet模型介绍及其Pytorch实现【含完整代码】

目录1. AlexNet模型1.1 AlexNet与LeNet的区别1.2 简化的AlexNet实现1.3 各层输出形状详解2. 读取数据3. 模型训练4. 总结上一篇文章中我们了解到神经网络可以直接基于图像的原始像素进行分类&#xff0c;这种称为端到端&#xff08;end-to-end&#xff09;的方法可以节省很多中…

腾讯实践:从推荐模型的基础特点看大规模推荐类深度学习系统的设计

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年11月份热门报告盘点腾讯新闻信息流推荐技术实践.pdf推荐系统在腾讯游戏中的应用实践.pdf基于深度学习的个性化推荐系统实时化改造与升级.pdf推荐技术在vivo互联网商业化…

Zabbix与乐维监控对比分析(四)——告警管理篇

在前面发布的Zabbix与乐维监控对比分析文章中&#xff0c;我们评析了二者在架构与性能、Agent管理、自动发现、权限管理、对象管理等方面的差异。接下来让我们一起看看二者在告警管理方面的差异。 告警管理是所有IT监控平台最重磅的功能之一&#xff0c;也是评判一个监控平台好…

cad2010怎么隐藏标注尺寸,cad2007怎么隐藏标注尺寸

1、CAD2007怎么隐藏所有的标注尺寸? 1、在"查看器"菜单面板中隐藏的工具有"线宽"、"测量"、"文本"三种工具,可用于隐藏或显示CAD图中的线条宽度、测量尺寸和文本内容。 2、点击选择"测量"工具,将尺寸内容的CAD图隐藏起来。…

JavaScript-BOM

&#x1f496;通过看视频教程和红宝书浅浅的写下一些关于BOM的笔记 红宝书知识系统全面&#xff0c;精炼。大概是因为太干货了&#xff0c;涉及的知识点太多&#xff0c;所以我选择看着简单的视频教程&#xff0c;同时打开红宝书。笔记的内容以红宝书为基准。 window对象 BOM的…

艾美捷内皮细胞生长添加剂解决方案

内皮细胞生长添加剂是一种培养基补充物&#xff0c;旨在体外优化人原代微血管内皮细胞的生长。这是一种无菌浓缩&#xff08;100X&#xff09;溶液&#xff0c;含有培养正常人微血管内皮细胞所需的生长因子、激素和蛋白质。该补充剂的配制&#xff08;定量和定性&#xff09;旨…

Linux下的多线程编程

线程&#xff08;thread&#xff09;技术早在60年代就被提出&#xff0c;但真正应用多线程到操作系统中去&#xff0c;是在80年代中期&#xff0c;solaris是这方面的佼佼者。传统的Unix也支持线程的概念&#xff0c;但是在一个进程&#xff08;process&#xff09;中只允许有一…

基于java+springmvc+mybatis+vue+mysql的教资考前指导系统

项目介绍 对于本教资考前指导系统的设计来说&#xff0c;系统开发主要是采用java语言技术&#xff0c;后端采用springboot框架&#xff0c;前端采用vue技术&#xff0c;在整个系统的设计中应用MySQL数据库来完成数据存储&#xff0c;具体根据教资考前指导系统的现状来进行开发…

Metasploit Framework简介

没有框架渗透测试者的困扰 ● 需要掌握数百个工具软件&#xff0c;上千个命令参数&#xff0c;实在记不住 ● 新出现的漏洞PoC/EXP有不同的运行环境要求&#xff0c;准备工作繁琐 ● 大部分时间都在学习不同工具的使用习惯&#xff0c;如果能同意就好了 ● Metasploit能解决以上…

pyinstaller遇到的问题

我到底看看能有多少问题&#xff0c;真的烦死我了&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#…

[附源码]Python计算机毕业设计公交电子站牌管理系统软件Django(程序+LW)

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

HAProxy走私漏洞

HAProxy走私漏洞 JFrog安全研究团队发布了一个HAProxy的严重漏洞的信息。HAProxy是一个使用C语言编写的自由及开放源代码软件&#xff0c;其提供高可用性、负载均衡&#xff0c;以及基于TCP和HTTP的应用程序代理。 参考文章&#xff1a;https://jfrog.com/blog/critical-vulne…

虚拟生产、交付、体验,元宇宙技术对供应链的深远影响#低碳生活

#背景自新冠肺炎疫情爆发以来&#xff0c;元宇宙增长速度加快&#xff0c;也推动了对远程工作工具的前所未有的需求。目前全球元宇宙市场估值高于 1000 亿美元&#xff0c;据预计&#xff0c;到 2029 年&#xff0c;预计年均增长 47 %&#xff0c;达到 15270 亿美元。#改造供应…

【DevOps实战系列】第三章:详解Maven仓库及环境搭建

个人亲自录制全套DevOps系列实战教程 &#xff1a;手把手教你玩转DevOps全栈技术 Maven私有仓库&#xff0c;就不多说了&#xff0c;我们这里选用最新的Nexus3的3.17版本&#xff0c;平时公司使用的都是Nexus 2.x,新的3.x版本做了很多的升级&#xff0c;包括存储方式等&#xf…

self.eval_net.forward(state)和self.eval_net.forward(state)区别

在根据状态获取一个动作&#xff1a;self.eval_net.forward(state) 在更新网络时&#xff1a;self.eval_net(state) 这2个有什么区别呀&#xff0c;为啥不都是forward 我打印了一下返回值的时候&#xff0c;我感觉格式是一样的 action_value tensor([[0.7177, 0.7369, 0.7124,…

amfori BSCI行为守则(2021)最新版-2023年生效

【amfori BSCI行为守则(2021)最新版-2023年生效】 amfori BSCI 商界社会责任倡议&#xff08;Business Social Compliance Initiative, BSCI&#xff09;是一套国际通用的企业社会责任管理工具和验厂标准。amfori BSCI 颁布行为守则&#xff08;Code of Conduct&#xff09;&am…

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

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

非地面无线通信网络的增强技术

【摘 要】通过增强基础地面网络,使之与星载或空载网络融合,可将地面通信网络应用推广到覆盖范围更广的非地面通信网络。分析非地面网络超大传输时延、多普勒效应、小区移动等通信条件对无线通信接口设计的影响,从标准化角度分析同步过程、定时关系、HARQ、波束管理与极化方…

C语言之文件操作

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【C/C】 目录文件的打开和关闭文件打开"r""w"注意有一个小细节文件的顺序读写字符输入输出函数fgetc和fputcfputcfg…