布隆过滤器判断某值是否可能已插入集合,核心是用byte[]或long[]模拟位数组,配合多个哈希函数映射到位索引,添加时置对应位为1,查询时检查所有位是否均为1。

布隆过滤器不直接判断 Java 中的“变量是否存在”(如局部变量、字段名),它判断的是**某个具体值是否可能已插入过集合**。实现核心是用数组模拟位数组,配合多个哈希函数完成位映射与判定。
用普通数组模拟位数组
Java 没有原生 bit 数组类型,但可以用 byte[] 或 long[] 实现紧凑位存储:
-
byte[]:每个 byte 存 8 位,下标
i对应第(i / 8)个字节,位偏移为i % 8 -
long[]:更高效,每个 long 存 64 位,下标
i对应第(i >> 6)个 long,位偏移为i & 63 - 初始化时全部置 0(
new byte[size]默认为 0)
关键:多个独立哈希函数映射到位索引
对输入值(如 String、Integer)计算 k 个不同哈希值,并统一映射到 [0, m) 范围内:
- 推荐用 MurmurHash3、XXHash 或 Java 内置
Objects.hash()配合不同 seed - 避免简单取模导致分布不均:用
hash & (m - 1)(要求 m 是 2 的幂)或Math.abs(hash) % m - 例如 k=3 时,对字符串 "user123" 计算:
h1 = hash(s, 1) % m、h2 = hash(s, 2) % m、h3 = hash(s, 3) % m
添加元素:把对应位设为 1
对每个哈希位置 index,在数组中定位并置位:
- 若用
long[] bits,执行:bits[index >> 6] |= (1L - 确保所有 k 个位置都执行该操作,顺序无关
- 注意:同一位置多次置 1 无副作用
查询元素:检查所有 k 个位置是否全为 1
同样计算 k 个哈希位置,逐个读取对应位:
- 读取逻辑:
(bits[index >> 6] & (1L - 只要任一位置为 0,立即返回 false(确定不存在)
- 全部为 1 才返回 true(可能存在,有假阳性)
- 这个判定逻辑不可逆——布隆过滤器无法删除元素
实战示例:防缓存穿透校验
比如数据库查用户 ID,先过布隆过滤器快速拦截无效 ID:
- 预热阶段:将所有合法 user_id(如 1~1000 万)加入布隆过滤器
- 请求到达时,先
filter.mightContain("user_9999999") - 返回 false → 直接拒绝,不查缓存也不查 DB
- 返回 true → 继续走缓存 → 缓存 miss 再查 DB → DB 无结果则写空对象(防穿透)

















