我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java中的布隆过滤器你真的懂了吗

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java中的布隆过滤器你真的懂了吗

什么是布隆过滤器

布隆过滤器(Bloom Filter)是一种空间效率非常高的随机数据结构,它利用位数组(BitSet)表示一个集合,并通过一定数量的哈希函数将元素映射为位数组中的位置,用于检查一个元素是否属于这个集合。

实现的核心思想

对于一个元素,通过多个哈希函数生成多个哈希值,将对应的位在位数组中设为 1,若多个哈希值对应的位都为 1,则认为该元素可能在集合中;若至少有一个哈希值对应的位为 0,则该元素一定不在集合中。这种方法可以在较小的空间中实现高效的查找,但可能存在误判率(false positive)。

怎么理解

一个典型的布隆过滤器包含三个参数: 位数组的大小(即存储元素的个数); 哈希函数的个数; 填充因子(即误判率),即将元素数量与位数组大小的比值。

如上图所示: 布隆过滤器的基本操作流程,包括初始化位数组和哈希函数、插入元素、检查元素是否在集合中等。其中,每个元素都会被多个哈希函数映射到位数组中的多个位置,而在检查元素是否在集合中时,需要确保所有对应的位都被设置为 1,才会认为该元素可能在集合中。

典型应用场景

垃圾邮件过滤: 将所有的黑名单邮件对应的哈希值在布隆过滤器中对应的位置设为 1,对于每一封新邮件,将其哈希值在布隆过滤器中对应的位置检查是否都为 1,若是,则认为该邮件是垃圾邮件,否则可能是正常邮件;

URL 去重: 将已经抓取的 URL 对应的哈希值在布隆过滤器中对应的位置设为 1,对于每一条新的 URL,将其哈希值在布隆过滤器中对应的位置检查是否都为 1,若是,则认为该 URL 已经抓取过,否则需要进行抓取;

缓存击穿: 将缓存中存在的所有数据对应的哈希值在布隆过滤器中对应的位置设为 1,对于每一个查询的键值,将其哈希值在布隆过滤器中对应的位置检查是否都为 1,若是,则认为该键值存在于缓存中,否则需要从数据库中查询并将其添加到缓存中。

需要注意的是,布隆过滤器的误判率会随着位数组大小的增加而减小,但同时也会增加内存开销和计算时间。 为了方便理解布隆过滤器,下面用java代码实现一个简单的布隆过滤器:

import java.util.BitSet;
import java.util.Random;
public class BloomFilter {
  private BitSet bitSet;           // 位集,用于存储哈希值
  private int bitSetSize;         // 位集大小
  private int numHashFunctions;   // 哈希函数数量
  private Random random;          // 随机数生成器
  // 构造函数,根据期望元素数量和错误率计算位集大小和哈希函数数量
  public BloomFilter(int expectedNumItems, double falsePositiveRate) {
    this.bitSetSize = optimalBitSetSize(expectedNumItems, falsePositiveRate);
    this.numHashFunctions = optimalNumHashFunctions(expectedNumItems, bitSetSize);
    this.bitSet = new BitSet(bitSetSize);
    this.random = new Random();
  }
  // 根据期望元素数量和错误率计算最佳位集大小
  private int optimalBitSetSize(int expectedNumItems, double falsePositiveRate) {
    int bitSetSize = (int) Math.ceil(expectedNumItems * (-Math.log(falsePositiveRate) / Math.pow(Math.log(2), 2)));
    return bitSetSize;
  }
  // 根据期望元素数量和位集大小计算最佳哈希函数数量
  private int optimalNumHashFunctions(int expectedNumItems, int bitSetSize) {
    int numHashFunctions = (int) Math.ceil((bitSetSize / expectedNumItems) * Math.log(2));
    return numHashFunctions;
  }
  // 添加元素到布隆过滤器中
  public void add(String item) {
    // 计算哈希值
    int[] hashes = createHashes(item.getBytes(), numHashFunctions);
    // 将哈希值对应的位设置为 true
    for (int hash : hashes) {
      bitSet.set(Math.abs(hash % bitSetSize), true);
    }
  }
  // 检查元素是否存在于布隆过滤器中
  public boolean contains(String item) {
    // 计算哈希值
    int[] hashes = createHashes(item.getBytes(), numHashFunctions);
    // 检查哈希值对应的位是否都为 true
    for (int hash : hashes) {
      if (!bitSet.get(Math.abs(hash % bitSetSize))) {
        return false;
      }
    }
    return true;
  }
  // 计算给定数据的哈希值
  private int[] createHashes(byte[] data, int numHashes) {
    int[] hashes = new int[numHashes];
    int hash1 = Math.abs(random.nextInt());
    int hash2 = Math.abs(random.nextInt());
    for (int i = 0; i < numHashes; i++) {
      // 使用两个随机哈希函数计算哈希值
      hashes[i] = Math.abs((hash1 * i) + (hash2 * i) + i) % data.length;
    }
    return hashes;
  }
}

以上就是Java中的布隆过滤器你真的懂了吗的详细内容,更多关于Java布隆过滤器的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java中的布隆过滤器你真的懂了吗

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java中的布隆过滤器你真的懂了吗

经常会听到大家说起布隆过滤器,但是很多人都只是听过名字,却并不知道其是怎么实现的。下面将详细介绍一下布隆过滤器,并且使用简单的代码演示
2023-05-18

Java的布隆过滤器如何实现

今天小编给大家分享一下Java的布隆过滤器如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。BitMap现代计算机用二进
2023-06-29

Redis中Bloomfilter布隆过滤器的学习

布隆过滤器是一个非常长的二进制向量和一系列随机哈希函数的组合,可用于检索一个元素是否存在,本文就详细的介绍一下Bloomfilter布隆过滤器,具有一定的参考价值,感兴趣的可以了解一下
2022-12-14

Redis中Bloom filter布隆过滤器的学习

目录1.概念2.guava实现2.1.依赖2.2.初始化布隆过滤器2.3.布隆过滤器2.4.添加元素或者判断是否存在3.Redisson实现3.1.依赖3.2.注入或测试1.概念​ 布隆过滤器是一个高空间利用率的概率性数据结构,主要目的是
2022-12-14

Java中的布隆过滤器原理实现和应用

Java中的布隆过滤器是一种基于哈希函数的数据结构,能够高效地判断元素是否存在于一个集合中。它广泛应用于缓存、网络协议、数据查询等领域,在提高程序性能和减少资源消耗方面具有显著优势
2023-05-17

Java布隆过滤器的原理和实现分析

数组、链表、树等数据结构会存储元素的内容,一旦数据量过大,消耗的内存也会呈现线性增长所以布隆过滤器是为了解决数据量大的一种数据结构。本文就来和大家详细说说布隆过滤器的原理和实现,感兴趣的可以了解一下
2022-11-13

十分钟带你读懂Vue中的过滤器

过滤器提供给我们的一种数据处理方式。过滤器功能不是必须要使用的,因为它所实现的功能也能用计算属性或者函数调用的方式来实现。这篇文章主要为大家介绍了Vue中过滤器的使用,需要的可以了解一下
2023-03-11

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录