1%误判率只要23KB,这个Java布隆过滤器工具类有10个方法

简介: 这是一个轻量级布隆过滤器工具类,基于JDK 17+,支持按预期容量与误判率自动计算位数组长度与哈希个数,提供字符串/字节数组增删查、填充率及理论误判率评估等功能,2万元素仅占23KB,高效防缓存穿透。

📋 目录

一、工具类功能

用极小的内存判断元素「一定不存在」还是「可能存在」,按预期插入量和目标误判率自动定位数组长度与哈希个数,2 万个元素按 1% 误判率只要 23 KB。

二、所需环境

JDK 17或以上

三、方法与调用示例(按需调用)

🔢 方法序号:1

🎯 方法用途:

  • 由预期插入数与目标误判率推导位数组要多长,先算再建实例
  • 评估一个布隆过滤器要吃多少内存时用,容量与误判率是这一对参数定的

🧩 方法定义:public static long optimalBitSize(long expectedInsertions, double fpp)

🗣️ 入参解释:public static long optimalBitSize(预期插入数, 目标误判率)

📤 返回值解释:long,需要的位数

💡 边界口径:

  • 单个实例最大 2^31-1 位(约 256MB),超出直接拒绝,要更大容量按业务维度分片建多个实例
  • fpp 必须落在开区间 (0, 1),expectedInsertions 必须大于 0,违反抛 IllegalArgumentException
  • 别指望放大 expectedInsertions 自动扩容,那只会把误判率静默抬高
  • 结果是公式值,不是实测占用字节

🧪 方法示例:

  • optimalBitSize(20_000, 0.01) 拿到 191702,约合 23 KB
  • optimalBitSize(1_000_000_000L, 1e-9) 抛 所需bit数43132762699超出单个实例上限2147483647位(约256MB),请分片或使用多实例
  • optimalBitSize(1000, 1.0) 抛 误判率必须在(0,1)之间,当前为1.0
  • optimalBitSize(0, 0.01) 抛 预期插入数必须大于0,当前为0

🔢 方法序号:2

🎯 方法用途:

  • 由位数与预期插入数推导每个元素要设置几个哈希位置
  • 与位数组长度配套,哈希个数太少误判率高、太多则白算

🧩 方法定义:public static int optimalHashCount(long bitSize, long expectedInsertions)

🗣️ 入参解释:public static int optimalHashCount(bit位数, 预期插入数)

📤 返回值解释:int,每个元素的哈希位置个数

💡 边界口径:

  • 位数与预期插入数都必须大于 0,否则抛 IllegalArgumentException
  • 这里算出的个数会被 create 用进双重哈希,h(i) = h1 + i × h2
  • 结果至少为 1,不会出现一个哈希位都不设的过滤器

🧪 方法示例:

  • optimalHashCount(191702, 20_000) 拿到 7 个哈希位置
  • optimalHashCount(0, 10) 抛 bit位数必须大于0,当前为0
  • optimalHashCount(191702, 0) 抛 预期插入数必须大于0,当前为0

🔢 方法序号:3

🎯 方法用途:

  • 按当前装载量算理论误判率,用来看过滤器还在不在可用区间
  • 插入量超预期后误判率会明显爬升,这个数是趋势观测的入口

🧩 方法定义:public static double expectedFpp(long bitSize, int hashCount, long inserted)

🗣️ 入参解释:public static double expectedFpp(bit位数, 哈希个数, 已插入数)

📤 返回值解释:double,理论误判率,0 到 1 之间

💡 边界口径:

  • 一条都没灌时给 0.0,装载越多越接近 1
  • inserted 取的是 insertedCount(),重复添加也计入,所以这是乐观估计
  • 位数或哈希个数不合法抛 IllegalArgumentException
  • 是公式值不是实测值,实测要拿不存在的 key 去探测

🧪 方法示例:

  • expectedFpp(191702, 7, 0) 拿到 0.0,刚建好时没有误判
  • 灌到 2 万条时拿到 0.010039010484203732,与设定的 0.01 对得上
  • 灌到 4 倍量之后抬到 0.6786804119833408
  • 位数被灌满时 expectedFpp(191702, 7, 191702) 拿到 0.9936342618294455

🔢 方法序号:4

🎯 方法用途:

  • 按推导出的位数与哈希个数建一个过滤器实例
  • 日常用这一版就够,参数只给预期插入数和目标误判率

🧩 方法定义:public static BloomFilter create(long expectedInsertions, double fpp)

🗣️ 入参解释:public static BloomFilter create(预期插入数, 目标误判率)

📤 返回值解释:BloomFilter,可增可查的实例,非线程安全

💡 边界口径:

  • 位数组与哈希个数都由前两个方法推导,不接受手工指定
  • 实例本身内部是无锁 BitSet 与计数,多线程共享要外部加锁或分片
  • 建好时填充率为 0,容量与 expectedInsertions 一致
  • 参数非法与超上限的报错口径同 optimalBitSize

🧪 方法示例:

  • create(20_000, 0.01).bitFillRatio() 拿到 0.0,还没灌数据
  • create(1_000_000_000L, 1e-9) 抛 所需bit数43132762699超出单个实例上限2147483647位(约256MB),请分片或使用多实例

🔢 方法序号:5

🎯 方法用途:

  • 把字符串元素按 UTF-8 编码后放进过滤器
  • 订单号、手机号、URL 这类文本判重场景的写入口

🧩 方法定义:public void add(String value)

🗣️ 入参解释:public void add(字符串元素)

📤 返回值解释:void,写入后不返回什么,查询走 mightContain

💡 边界口径:

  • 判重按字节走,"中文" 与它的转义字面量是两个不同元素
  • 传 null 抛 NullPointerException,避免所有槽位塌陷到 0 号位污染过滤器
  • 每次调用都让 insertedCount 加一,重复元素也计

🧪 方法示例:

  • 灌完 2 万条字符串之后 insertedCount() 拿到 20001,多的一条来自字节入口
  • 加过的 key 用 mightContain("ORD1000001") 查得到,拿到 true(不可能漏)
  • add(null) 抛 字符串不能为null

🔢 方法序号:6

🎯 方法用途:

  • 字节数组入口写入,与字符串入口同一套哈希与槽位
  • 已经是摘要、ID 字节或不想再编码一次的场合用它

🧩 方法定义:public void add(byte[] value)

🗣️ 入参解释:public void add(字节数组元素)

📤 返回值解释:void,写入即生效

💡 边界口径:

  • 同一内容的字节与字符串入口互通,字节灌进去的字符串入口查得到
  • 传 null 抛 NullPointerException,消息是 元素字节不能为null
  • 空数组是合法元素,会占用一组槽位

🧪 方法示例:

  • 字节入口灌进去的,mightContain 用字符串查拿到 true
  • mightContain("ORD1000001".getBytes(StandardCharsets.UTF_8)) 拿到 true,两个入口口径一致
  • add((byte[]) null) 抛 元素字节不能为null

🔢 方法序号:7

🎯 方法用途:

  • 查字符串元素是否可能存在,返回 false 是「一定不存在」
  • 缓存穿透拦截、海量数据预筛这类只要求「别把没有的放过去」的场景用它

🧩 方法定义:public boolean mightContain(String value)

🗣️ 入参解释:public boolean mightContain(字符串元素)

📤 返回值解释:boolean,false 一定不存在,true 只是可能存在

💡 边界口径:

  • true 不能当权威结论,后面还要回源确认
  • 装载越满误判越多,配合 bitFillRatio 与 expectedFpp 观察
  • 按 UTF-8 判重,转义字面量与原字符不是同一个元素
  • 传 null 抛 NullPointerException

🧪 方法示例:

  • 加过的 key mightContain(added) 拿到 true,不可能漏
  • 没加过的 key mightContain(missing) 拿到 false,一定不存在可以放心拦截
  • 转义字面量 mightContain("\u4E2D\u6587") 拿到 false,它不是同一个元素
  • 灌到 4 倍量之后,同样 2 万次不存在 key 的探测命中数拿到 从 200 涨到 13435,过滤器已经不再省钱
  • mightContain((String) null) 抛 字符串不能为null

🔢 方法序号:8

🎯 方法用途:

  • 字节形态的查询入口,结论与字符串版一致
  • 上游给的是原始字节(摘要、协议体)时用这一版

🧩 方法定义:public boolean mightContain(byte[] value)

🗣️ 入参解释:public boolean mightContain(字节数组元素)

📤 返回值解释:boolean,false 一定不存在,true 只是可能存在

💡 边界口径:

  • 与字符串入口共用哈希与位数组,同一字节内容两边结论相同
  • 传 null 抛 NullPointerException
  • 判的是位是否被置起,不看是谁置的,这就是误判来源

🧪 方法示例:

  • 没写过的字节数组 mightContain(missing.getBytes(StandardCharsets.UTF_8)) 拿到 false
  • 写过的 mightContain("SKU1005000".getBytes(StandardCharsets.UTF_8)) 拿到 true,与字符串入口结论一致
  • 与 mightContain(String) 对同一份内容比对,拿到 true

🔢 方法序号:9

🎯 方法用途:

  • 读 add 的调用次数,用来喂理论误判率公式
  • 监控装载量、判断是否已经超出预期插入数时看它

🧩 方法定义:public long insertedCount()

🗣️ 入参解释:public long insertedCount()(无入参)

📤 返回值解释:long,累计 add 调用次数

💡 边界口径:

  • 重复添加同样计数,它不是去重后的元素个数
  • 只做乐观估计,理论误判率会因此偏低
  • 计数只增不减,本类没有删除元素的入口

🧪 方法示例:

  • 灌到 4 倍量之后 insertedCount() 拿到 80001
  • 同一元素 add 两次后拿到 2,重复添加照计

🔢 方法序号:10

🎯 方法用途:

  • 读位数组的填充率,越接近 1 说明越失控
  • 判断「该重建或分片了」比看插入数更直接,用它

🧩 方法定义:public double bitFillRatio()

🗣️ 入参解释:public double bitFillRatio()(无入参)

📤 返回值解释:double,已置起的位占总位数的比例

💡 边界口径:

  • 刚建好是 0.0,灌满接近 1.0,此时任何 key 都会被判「可能存在」
  • 是实测的位占用比例,与 expectedFpp 的理论值互补
  • 读它不改动过滤器状态,可安全用于监控埋点

🧪 方法示例:

  • 按 2 万条设计的过滤器灌到 4 倍量后 bitFillRatio() 拿到 0.9454309292547809
  • 新建实例 create(100, 0.03).bitFillRatio() 拿到 0.0

四、工具类源码(可直接复制)

📦 源码文件

相关文章
|
6天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
2764 22
|
1天前
|
云安全 人工智能 安全
|
5天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
|
6天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
1235 5
|
云安全 安全 网络安全
|
7天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
|
19天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
3354 52
|
11天前
|
人工智能 JSON Linux
【保姆级】ComfyUI部署教程(下载+安装+配置+工作流,2026最新)
ComfyUI 是一款开源节点式AI生成工具,支持图像、视频、音频及3D内容创作。通过拖拽连线组合模型加载、提示词、采样等节点,构建可复用、易修改的工作流,兼容SD1.5、SDXL、Flux、Qwen Image等主流模型。