基于Guava布隆过滤器的海量字符串高效去重实践

在Java环境中处理海量字符串去重的问题时,布隆过滤器(BloomFilter)是一种非常高效的数据结构,尽管它有一定的误报率。布隆过滤器适用于那些可以接受一定误报率,并且希望节省空间和时间成本的场景。
在这里插入图片描述

布隆过滤器应用

使用Google Guava库来实现基于布隆过滤器的海量字符串去重是一个很好的选择。布隆过滤器是一种空间效率极高的概率型数据结构,它利用位数组表示集合,并使用哈希函数将元素映射到位数组的某些位置。布隆过滤器可以高效地检查一个元素是否可能属于某个集合,但有一定的误报率。

首先,确保你的项目中包含了Guava库。如果你使用Maven,可以在pom.xml文件中添加以下依赖:

<dependency>  
    <groupId>com.google.guava</groupId>  
    <artifactId>guava</artifactId>  
    <version>31.0.1-jre</version> <!-- 使用你需要的版本 -->  
</dependency>

然后,你可以使用下面代码创建布隆过滤器进行字符串去重:

import com.google.common.hash.Funnels;  
import com.google.common.primitives.Ints;  
import com.google.common.util.concurrent.BloomFilter;  
  
import java.nio.charset.StandardCharsets;  
import java.util.ArrayList;  
import java.util.List;  
  
public class BloomFilterDeduplication {  
  
    public static void main(String[] args) {  
        // 预计的字符串数量(根据实际情况进行调整)  
        long expectedInsertions = 1000000L;  
        // 可接受的误报率(根据实际情况进行调整)  
        double fpp = 0.01; // 1%的误报率  
  
        // 创建一个布隆过滤器实例  
        BloomFilter<String> bloomFilter = BloomFilter.create(  
                Funnels.stringFunnel(StandardCharsets.UTF_8),  
                expectedInsertions,  
                fpp  
        );  
  
        // 模拟海量字符串  
        List<String> strings = new ArrayList<>();  
        // 假设这里有很多重复的字符串...  
        strings.add("hello");  
        strings.add("world");  
        strings.add("hello"); // 重复字符串  
        strings.add("guava");  
        strings.add("bloom");  
        strings.add("filter");  
        strings.add("world"); // 重复字符串  
  
        // 去重过程  
        List<String> deduplicatedStrings = new ArrayList<>();  
        for (String str : strings) {  
            if (!bloomFilter.mightContain(str)) {  
                // 如果布隆过滤器中可能不包含该字符串,则将其添加到过滤器和结果列表中  
                bloomFilter.put(str);  
                deduplicatedStrings.add(str);  
            }  
        }  
  
        // 输出结果  
        System.out.println("Deduplicated strings:");  
        for (String uniqueStr : deduplicatedStrings) {  
            System.out.println(uniqueStr);  
        }  
    }  
}

在这个示例中,我们首先创建了一个布隆过滤器实例,指定了预计的字符串数量和可接受的误报率。然后,我们模拟了一个包含重复字符串的列表,并使用布隆过滤器进行去重。对于每个字符串,如果布隆过滤器可能不包含它(mightContain返回false),我们就将其添加到过滤器和去重后的字符串列表中。

布隆过滤器原理详解

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

布隆过滤器可以告诉我们 “某样东西一定不存在或者可能存在”,也就是说布隆过滤器说这个数不存在则一定不存,布隆过滤器说这个数存在可能不存在(误判,后续会讲)。

布隆过滤器是一种空间效率极高的概率型数据结构,它利用位数组表示集合,并使用哈希函数将元素映射到位数组的某些位置。布隆过滤器并不直接存储数据本身,而是通过位数组中的特定位来表示数据是否存在。

布隆过滤器的数据结构主要由两部分组成:

  • 位数组(Bit Array):布隆过滤器使用一个长度固定的位数组来存储数据。每个位置只占用一个比特(0或1),初始时所有位都设置为0。位数组的长度和哈希函数的数量决定了过滤器的误报率和容量。

  • 哈希函数集合:布隆过滤器使用多个哈希函数,每个函数都会将输入数据映射到位数组的一个不同位置。哈希函数的选择对过滤器的性能有很大影响,理想的哈希函数应该具有良好的散列性,使得不同的输入尽可能均匀地映射到位数组的不同位置。

如下就是一个简单的布隆过滤器示意图,其中k1、k2代表增加的元素,a、b、c即为无偏hash函数,最下层则为二进制数组。
在这里插入图片描述

布隆过滤器的操作主要包括:

  • 添加元素:当向布隆过滤器中添加一个新元素时,会使用所有的哈希函数对该元素进行哈希,并将位数组中对应位置设置为1。注意,同一个位可能会被多个元素哈希到,因此可能会被多次设置为1,但实际上只需要第一次设置。

例如,key = Liziba,无偏hash函数的个数k=3,分别为hash1、hash2、hash3。三个hash函数计算后得到三个数组下标值,并将其值修改为1

  • 查询元素:当需要查询一个元素是否可能存在于布隆过滤器中时,同样会使用所有的哈希函数对该元素进行哈希,并检查位数组中对应位置是否都为1。如果有任何一个位置为0,则可以确定该元素一定不在过滤器中。如果所有位置都为1,则元素可能存在于过滤器中,但存在一定的误报率。

  • 删除元素:布隆过滤器不支持直接删除元素。这是因为删除一个元素需要将位数组中对应位置重置为0,但这样可能会影响到其他也被哈希到该位置的元素。因此,布隆过滤器是一种“添加容易,删除困难”的数据结构。

布隆过滤器的好处

  • 空间效率:布隆过滤器不需要存储实际数据,只需要一个位数组和一些哈希函数,因此空间效率非常高。
  • 查询速度:布隆过滤器的查询操作只需要进行哈希和位操作,因此速度非常快。
  • 添加速度:添加元素到布隆过滤器中同样只需要进行哈希和位操作,速度也很快。
  • 安全性:布隆过滤器不存储实际数据,因此在某些对安全性要求较高的场景中很有用。
    需要注意的是,布隆过滤器有一定的误报率。这是因为不同的元素可能会哈希到相同的位置,导致位数组中对应位置被错误地设置为1。此外,布隆过滤器不支持删除操作,因为删除一个元素可能会影响到其他元素。

布隆过滤器的缺点

  • 误报率:布隆过滤器有一定的误报率,即可能会错误地认为某个不在集合中的元素在集合中。误报率与二进制向量的长度和哈希函数的数量有关,可以通过调整这两个参数来控制误报率。
  • 无法删除元素:由于布隆过滤器的特性,一旦一个元素被添加到过滤器中,就无法从过滤器中删除。这是因为删除元素可能会导致其他元素被误删。

总的来说,布隆过滤器是一种非常适合处理海量数据去重问题的数据结构,尤其是在空间和时间成本都非常敏感的场景下。虽然它有一定的误报率,但在很多应用中,这个缺点是可以接受的。在使用布隆过滤器时,需要根据具体的应用场景和需求来调整参数,以达到最佳的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/343516.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

爬取的数据可以入表吗?怎样入表?

合规是数据入表的前提。当前爬虫数据是非常敏感的&#xff0c;因为爬虫极容易造成两大不合规的问题&#xff1a;一是没有经过个人同意获取数据&#xff0c;二是爬取的数据里可能含有个人敏感信息也是一个问题。现在法律对于这部分非常严苛&#xff0c;如果企业里有50条未获得授…

优先级队列(堆)详解

优先级队列&#xff08;堆&#xff09;详解 目录 堆的概念堆的存储方式堆的基本操作优先级队列模拟实现PriorityQueue接口介绍堆排序Top-k问题 1、堆的概念 如果有一个关键码的集合K {k0&#xff0c;k1&#xff0c; k2&#xff0c;…&#xff0c;kn-1}&#xff0c;把它的所…

动态规划—— 求最长不下降序列LIS【集训笔记】

题目描述 设有由n(1≤n≤200)个整数组成的数列&#xff0c;记为:b(1)、b(2)、……、b(n)&#xff0c;若存在i1<i2<i3<…<ie 且有b(i1)<b(i2)<…<b(ie)则称为长度为e的不下降序列。程序要求&#xff0c;当原数列出之后&#xff0c;求出最长的不下降序列。 …

仰暮计划|“她告诉我,大部分时间她都是一个家庭主妇,负责照料家务和小孩,但她从来没有停止她对知识的追求”

我来到河南省开封市兰考县南北庄村内一个宁静而温馨的小院子&#xff0c;那里居住着一位九十多岁的高龄老人&#xff0c;她就是张奶奶。张奶奶是村里的一位高龄老人&#xff0c;拥有着丰富的人生经历。我对她的故事非常充满好奇&#xff0c;所以特地来到张奶奶的家中&#xff0…

5.Nacos注册中心

5.Nacos注册中心 国内公司一般都推崇阿里巴巴的技术&#xff0c;比如注册中心&#xff0c;SpringCloudAlibaba也推出了一个名为Nacos的注册中心。 5.1.认识和安装Nacos Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c…

【加解密篇】电子数据取证分析之特殊的自加密BitLocker解密

【加解密篇】电子数据取证分析之特殊的自加密BitLocker解密 数据加解密通常是个耗时费力的事情—【蘇小沐】 1、实验环境 Windows 11 专业版&#xff0c;[23H2&#xff08;22631.3007&#xff09;] &#xff08;一&#xff09;自动开启BitLocker之天坑 1、经验之谈 在201…

常用电子器件学习——MOS管

MOS管介绍 MOS&#xff0c;是MOSFET的缩写。MOSFET 金属-氧化物半导体场效应晶体管&#xff0c;简称金氧半场效晶体管&#xff08;Metal-Oxide-Semiconductor Field-Effect Transistor, MOSFET&#xff09;。 一般是金属(metal)—氧化物(oxide)—半导体(semiconductor)场效应晶…

尝试为ssrf漏洞编写黑名单与白名单

以pikachu靶场ssrf&#xff08;curl&#xff09;为例&#xff1a; 你会发现什么也没防御项访问基本的文件内容&#xff0c;端口开放都是可以看到的&#xff0c;没有任何防御措施。 我们去查看一下他的源码有没有过滤什么 没有任何过滤&#xff0c;咱么尝试进行过滤一下&#xf…

P9232 [蓝桥杯 2023 省 A] 更小的数

[蓝桥杯 2023 省 A] 更小的数 终于本弱一次通关了一道研究生组别的题了[普及/提高−] 一道较为简单的双指针题,但一定有更好的解法. 题目描述 小蓝有一个长度均为 n n n 且仅由数字字符 0 ∼ 9 0 \sim 9 0∼9 组成的字符串&#xff0c;下标从 0 0 0 到 n − 1 n-1 n−1&a…

防御第二次作业-防火墙组网实验(2)

目录 实验拓扑图 实验要求 一般组网步骤 to isp区域ping通 dmz区域 trust区域 实验拓扑图 实验要求 1.防火墙向下使用子接口分别对应两个内部区域 2.所有分区设备可以ping通网关 一般组网步骤 1.先配ip、接口、区域、安全策略 2.内网配置回包路由 3.配置dmz区域的服务器映…

工业物联网水泵远程监控系统解决方案

行业描述 水泵作为一种应用极为广泛的通用机械&#xff0c;在工业生产、日常生活中发挥着重要作用&#xff0c;伴随着“十三五”期间重大工程泵类产品的国产化率的提高&#xff0c;当前已经基本满足了国家经济建设发展的需要。 近年来中国水泵企业实现了较大的技术提升&#…

JavaWeb之开发介绍 --黑马笔记

什么是 Web &#xff1f; Web&#xff1a;全球广域网&#xff0c;也称为万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 Web 网站的工作流程 上图解释&#xff1a; 当你在浏览器中输入网址或点击一个链接时&#xff0c;浏览器会向前端服务器发起请求&…

一文让你了解UI自动化测试

测试都起什么作用 - 是项目的保险&#xff0c;但不是项目的救命草&#xff1b;测试无实际产出&#xff0c;但作用远大于实际产出&#xff1b;测试是从项目维度保证质量&#xff0c;而不是测试阶段。 UI自动化&#xff08;下面简称自动化&#xff09; - 基于UI进行自动功能测试…

贪心算法详解

文章目录 前言一、什么是贪心算法二、贪心算法的特点1.贪心策略的提出2.贪心策略的正确性 三、学习贪心算法的方向总结 前言 在本次文章中我们将会详细介绍贪心算法的相关内容 一、什么是贪心算法 贪心算法&#xff1a;在解决问题时&#xff0c;每一步都选择最优解&#xff0…

K8s(九)持久化存储PV与PVC

PV和PVC PV 和 PVC 之间的关系是一种动态的供需匹配关系。PVC 表示应用程序对持久化存储的需求&#xff0c;而 PV 表示可用的持久化存储资源。Kubernetes 控制平面会根据 PVC 的需求来选择和绑定合适的 PV&#xff0c;将其挂载到应用程序的 Pod 中&#xff0c;从而使应用程序可…

Mock大法:Fake it till u make it!

在单元测试时&#xff0c;我们希望测试环境尽可能单纯、可控。因此我们不希望依赖于用户输入&#xff0c;不希望连接无法独占的数据库或者第三方微服务等。这时候&#xff0c;我们需要通 mock 来模拟出这些外部接口。mock 可能是单元测试中最核心的技术。 无论是 unittest 还是…

【DeepLearning-1】 注意力机制(Attention Mechanism)

1.1注意力机制的基本原理&#xff1a; 计算注意力权重&#xff1a; 注意力权重是通过计算输入数据中各个部分之间的相关性来得到的。这些权重表示在给定上下文下&#xff0c;数据的某个部分相对于其他部分的重要性。 加权求和&#xff1a; 使用这些注意力权重对输入数据进行加权…

Flink(十五)【Flink SQL Connector、savepoint、CateLog、Table API】

前言 今天一天争取搞完最后这一部分&#xff0c;学完赶紧把 Kafka 和 Flume 学完&#xff0c;就要开始做实时数仓了。据说是应届生得把实时数仓搞个 80%~90% 才能差不多找个工作&#xff0c;太牛马了。 1、常用 Connector 读写 之前我们已经用过了一些简单的内置连接器&#x…

用ChatGPT教学、科研!大学与OpenAI合作

亚利桑那州立大学&#xff08;简称“ASU”&#xff09;在官网宣布与OpenAI达成技术合作。从2024年2月份开始&#xff0c;为所有学生提供ChatGPT企业版访问权限&#xff0c;主要用于学习、课程作业和学术研究等。 为了帮助学生更好地学习ChatGPT和大语言模型产品&#xff0c;AS…

禅道的下载使用

文章目录 禅道的下载下载安装包 http://www.zentao.net/安装导南 禅道的使用创建用户产品经理将人员添加进禅道查看权限、产品经理使用禅道添加产品添加产品模块关联用例&#xff08;测试主管&#xff09;执行测试用例转bug 泳道图 禅道的下载 下载安装包 http://www.zentao.n…