当前位置:

首页 > 编程开发 > Java怎么实现布隆过滤器

Java怎么实现布隆过滤器

什么是布隆过滤器布隆过滤器(BloomFilter)是1970年由布隆提出来的。它实际上是由一个很长的二进制数组+一系列hash算法映射函数,用于判断一个元素是否存在于集合中。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。场景假设有10亿条手机号,然后判断某条手机号是否在列表内?mysql可以吗?正常情况下,如果数据量不大,我们可以考虑使用mysql存储。将所有数据存储到数据库,然后每次去库里查询判断是否存在。但是如果

本文目录

    什么是布隆过滤器

    布隆过滤器(Bloom Filter)是1970年由布隆提出来的。 它实际上是由一个很长的二进制数组+一系列hash算法映射函数,用于判断一个元素是否存在于集合中。
    布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

    场景

    假设有10亿条手机号,然后判断某条手机号是否在列表内?

    mysql可以吗?

    正常情况下,如果数据量不大,我们可以考虑使用mysql存储。将所有数据存储到数据库,然后每次去库里查询判断是否存在。但是如果数据量太大,超过千万,mysql查询效率是很低的,特别消耗性能。

    HashSet可以吗?

    我们可以把数据放入HashSet中,利用HashSet天然的去重性,查询只需要调用contains方法即可,但是hashset是存放在内存中的,数据量过大内存直接oom了。

    布隆过滤器特点

    • 插入和查询效率高,占用空间少,但是返回的结果是不确定的。

    • 一个元素如果判断为存在的时候,它不一定真的存在。但是如果判断一个元素不存在,那么它一定是不存在的。

    • 布隆过滤器可以添加元素,但是一定不能删除元素,会导致误判率增加。

    布隆过滤器原理

    布隆过滤器其实就是是一个BIT数组,通过一系列hash算法映射出对应的hash,然后将hash对应的数组下标位置改为1。查询时就是对数据在进行一系列hash算法得到下标,从BIT数组里取数据如如果是1 则说明数据有可能存在,如果是0 说明一定不存在

    为什么会有误差率

    我们知道布隆过滤器其实是对数据做hash,那么不管用什么算法,都有可能两条不同的数据生成的hash确是相同的,也就是我们常说的hash冲突。

    首先插入一条数据: 好好学技术

    Java怎么实现布隆过滤器

    在插入一条数据:

    Java怎么实现布隆过滤器

    这是如果查询一条数据,假设他的hash下标已经标为1了,那么布隆过滤器就会认为他存在

    Java怎么实现布隆过滤器

    常见使用场景

    缓存穿透

    java实现布隆过滤器

    package com.fandf.test.redis;
    
    import java.util.BitSet;
    
    /**
     * java布隆过滤器
     *
     * @author fandongfeng
     */
    public class MyBloomFilter {
    
        /**
         * 位数组大小
         */
        private static final int DEFAULT_SIZE = 2 << 24;
    
        /**
         * 通过这个数组创建多个Hash函数
         */
        private static final int[] SEEDS = new int[]{4, 8, 16, 32, 64, 128, 256};
    
        /**
         * 初始化位数组,数组中的元素只能是 0 或者 1
         */
        private final BitSet bits = new BitSet(DEFAULT_SIZE);
    
        /**
         * Hash函数数组
         */
        private final MyHash[] myHashes = new MyHash[SEEDS.length];
    
        /**
         * 初始化多个包含 Hash 函数的类数组,每个类中的 Hash 函数都不一样
         */
        public MyBloomFilter() {
            // 初始化多个不同的 Hash 函数
            for (int i = 0; i < SEEDS.length; i++) {
                myHashes[i] = new MyHash(DEFAULT_SIZE, SEEDS[i]);
            }
        }
    
        /**
         * 添加元素到位数组
         */
        public void add(Object value) {
            for (MyHash myHash : myHashes) {
                bits.set(myHash.hash(value), true);
            }
        }
    
        /**
         * 判断指定元素是否存在于位数组
         */
        public boolean contains(Object value) {
            boolean result = true;
            for (MyHash myHash : myHashes) {
                result = result && bits.get(myHash.hash(value));
            }
            return result;
        }
    
        /**
         * 自定义 Hash 函数
         */
        private class MyHash {
            private int cap;
            private int seed;
    
            MyHash(int cap, int seed) {
                this.cap = cap;
                this.seed = seed;
            }
    
            /**
             * 计算 Hash 值
             */
            int hash(Object obj) {
                return (obj == null) ? 0 : Math.abs(seed * (cap - 1) & (obj.hashCode() ^ (obj.hashCode() >>> 16)));
            }
        }
    
        public static void main(String[] args) {
            String str = "好好学技术";
            MyBloomFilter myBloomFilter = new MyBloomFilter();
            System.out.println("str是否存在:" + myBloomFilter.contains(str));
            myBloomFilter.add(str);
            System.out.println("str是否存在:" + myBloomFilter.contains(str));
        }
    
    
    }

    Guava实现布隆过滤器

    引入依赖

    
        com.google.guava
        guava
        31.1-jre
    
    package com.fandf.test.redis;
    
    import com.google.common.base.Charsets;
    import com.google.common.hash.BloomFilter;
    import com.google.common.hash.Funnels;
    
    /**
     * @author fandongfeng
     */
    public class GuavaBloomFilter {
    
        public static void main(String[] args) {
            BloomFilter bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),100000,0.01);
            bloomFilter.put("好好学技术");
            System.out.println(bloomFilter.mightContain("不好好学技术"));
            System.out.println(bloomFilter.mightContain("好好学技术"));
        }
    }

    hutool实现布隆过滤器

    引入依赖

    
        cn.hutool
        hutool-all
        5.8.3
    
    package com.fandf.test.redis;
    
    import cn.hutool.bloomfilter.BitMapBloomFilter;
    import cn.hutool.bloomfilter.BloomFilterUtil;
    
    /**
     * @author fandongfeng
     */
    public class HutoolBloomFilter {
        public static void main(String[] args) {
            BitMapBloomFilter bloomFilter = BloomFilterUtil.createBitMap(1000);
            bloomFilter.add("好好学技术");
            System.out.println(bloomFilter.contains("不好好学技术"));
            System.out.println(bloomFilter.contains("好好学技术"));
        }
    
    }

    Redisson实现布隆过滤器

    引入依赖

    
        org.redisson
        redisson
        3.20.0
    
    package com.fandf.test.redis;
     
    import org.redisson.Redisson;
    import org.redisson.api.RBloomFilter;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
     
    /**
     * Redisson 实现布隆过滤器
     * @author fandongfeng
     */
    public class RedissonBloomFilter {
     
        public static void main(String[] args) {
            Config config = new Config();
            config.useSingleServer().setAddress("redis://127.0.0.1:6379");
            //构造Redisson
            RedissonClient redisson = Redisson.create(config);
     
            RBloomFilter bloomFilter = redisson.getBloomFilter("name");
            //初始化布隆过滤器:预计元素为100000000L,误差率为1%
            bloomFilter.tryInit(100000000L,0.01);
            bloomFilter.add("好好学技术");
     
            System.out.println(bloomFilter.contains("不好好学技术"));
            System.out.println(bloomFilter.contains("好好学技术"));
        }
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Yandex官网入口及网页搜索使用方法
    Yandex官网入口及网页搜索使用方法

    Yandex官网入口是https://www.yondex.net/,该平台支持多语言切换、智能搜索匹配、虚拟键盘变更及实时翻译,提供地图、图片、新闻、购物等垂直服务,并具备账户同步、隐私管理、个性化首页和云存储等功能。

    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。