BitSet和布隆过滤器(Bloom Filter)

海量数据处理算法之Bloom Filter 算法介绍 Bloom Filter的中文名称叫做布隆过滤器,因为他最早的提出者叫做布隆(Bloom),因而而得此名。布隆过滤器简单的说就是为了检索一个元素是否存在于某个集合当中,以此实现数据的过滤。也许你会想,这还不简单,判断元素是否存在某集合中,遍历集合,一个个去比较不就能得出结果,当然这没有任何的问题,但是当你面对的是海量数据的时候,在空间和时间上的代价是非常恐怖的,显然需要更好的办法来 阅读详情

布隆过滤器

Bloom Filter 是由Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员。如果检测结果为是,该元素不一定在集合中;但如果检测结果为否,该元素一定不在集合中。因此Bloom filter具有100%的召回率。这样每个检测请求返回有“在集合内(可能错误)”和“不在集合内(绝对不在集合内)”两种情况,可见 Bloom filter 是牺牲了正确率和时间以节省空间。

 

当然布隆过滤器也有缺点,主要是误判的问题,随着数据量的增加,误判率也随着增大,解决办法:可以建立一个列表,保存哪些数值是容易被误算的。

Bloom Filter最大的特点是不会存在false negative,即:如果contains()返回false,则该元素一定不在集合中,但会存在一定的true negative,即:如果contains()返回true,则该元素可能在集合中。

Bloom Filter在很多开源框架都有实现,例如:

Elasticsearch:org.elasticsearch.common.util.BloomFilter

guava:com.google.common.hash.BloomFilter

Hadoop:org.apache.hadoop.util.bloom.BloomFilter(基于BitSet实现)

有兴趣可以看看源码。

BitSet的基本原理

最后再了解一下BitSet的基本原理,BitSet是位操作的对象,值只有0或1,内部实现是一个long数组,初始只有一个long数组,所以BitSet最小的size是64,当存储的数据增加,初始化的Long数组已经无法满足时,BitSet内部会动态扩充,最终内部是由N个long来存储,BitSet的内部扩充和List,Set,Map等得实现差不多,而且都是对于用户透明的。
1G的空间,有 8*1024*1024*1024=8589934592bit,也就是可以表示85亿个不同的数。

BitSet用1位来表示一个数据是否出现过,0为没有出现过,1表示出现过。在long型数组中的一个元素可以存放64个数组,因为Java的long占8个byte=64bit,具体的实现,看看源码:

首先看看set方法的实现:

 

public void set(int bitIndex) {
   if (bitIndex < 0)   //set的数不能小于0
        throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

   int wordIndex = wordIndex(bitIndex);//将bitIndex右移6位,这样可以保证每64个数字在long型数组中可以占一个坑。
   expandTo(wordIndex);

   words[wordIndex] |= (1L << bitIndex); // Restores invariants
   checkInvariants();
}

get命令实现:

public boolean get(int bitIndex) {
   if (bitIndex < 0)
       throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

   checkInvariants();

   int wordIndex = wordIndex(bitIndex);//和get一样获取数字在long型数组的那个位置。
   return (wordIndex < wordsInUse)
        && ((words[wordIndex] & (1L << bitIndex)) != 0);//在指定long型数组元素中获取值。
}

BitSet容量动态扩展:

 

private void ensureCapacity(int wordsRequired) {
   if (words.length < wordsRequired) {
        // Allocate larger of doubled size or required size
        int request = Math.max(2 * words.length, wordsRequired);//默认是扩大一杯的容量,如果传入的数字大于两倍的,则以传入的为准。
        // wordsRequired = 传入的数值右移6位 + 1
        words = Arrays.copyOf(words, request);
        sizeIsSticky = false;
   }
}

 

BitSet中实现了Cloneable接口,并定义在表中列出的方法:

SNMethods with 描述
1void and(BitSet bitSet)
与运算调用的内容BitSet中对象与那些指定bitSet。结果存放到调用对象。
2void andNot(BitSet bitSet)
对于bitSet每1位,在调用BitSet中的相应位清零。
3int cardinality( )
返回BitSet的容量。
4void clear( )
所有位清零。
5void clear(int index)
index指定的位清零。
6void clear(int startIndex, int endIndex)
将从startIndex到endIndex清零。
7Object clone( )
重复调用BitSet中对象。
8boolean equals(Object bitSet)
返回true如果调用位设置相当于一个在bitSet通过。否则,该方法返回false。
9void flip(int index)
逆转由index指定的位。 
10void flip(int startIndex, int endIndex)
反转将从startIndex位到endIndex.
11boolean get(int index)
返回指定索引处的位的当前状态。
12BitSet get(int startIndex, int endIndex)
返回一个BitSet中,它包含的比特将从startIndex到endIndex.1。调用对象不被改变。
13int hashCode( )
返回调用对象的哈希代码。
14boolean intersects(BitSet bitSet)
如果至少有一个对调用对象和bitSet内相应位为1,则返回true。
15boolean isEmpty( )
返回true如果在调用对象中的所有位均为零。
16int length( )
返回到持有调用BitSet中的内容所需的比特数。这个值是由最后1位的位置决定的。
17int nextClearBit(int startIndex)
返回下个清零位的索引,(即,下一个零位),从由startIndex指定的索引开始
18int nextSetBit(int startIndex)
返回下一组位(即,下一个1比特)的索引,从由startIndex指定的索引开始。如果没有位被设置,则返回1。
19void or(BitSet bitSet)
OR值调用的内容BitSet中对象,通过BitSet指定。结果被放置到调用对象。 
20void set(int index)
设置由index指定的位。
21void set(int index, boolean v)
设置由index指定在v. true为传递的值的位设置位,false则清除该位。
22void set(int startIndex, int endIndex)
设置位将从startIndex到endIndex.1。
23void set(int startIndex, int endIndex, boolean v)
设置位从startIndex到endIndex.1,在真正传递的值v设置位,清除位为false。
24int size( )
返回位在调用BitSet中对象的数量。
25String toString( )
返回字符串相当于调用BitSet中的对象。
26void xor(BitSet bitSet)

在异或调用BitSet中对象的内容与由BitSet指定。结果存放到调用对象。

 

BloomFilter的使用场景

 

1,爬虫的URL过滤。

2,日志分析

3,用户数统计等等等

总之使用布隆过滤器应该是可能容忍小概率误判的场景,不然慎用。。。

C++海量数据处理(二):布隆过滤器(Bloom Filter)详解 实例 、Bloom Filter算法描述 、Bloom Filter参数选择 阅读详情

相关推荐

避坑指南:用Adams做滚珠丝杠仿真时90%人会遇到的3个建模错误

本文针对使用Adams进行滚珠丝杠动力学仿真时常见的三大建模错误,提供了详细的避坑指南。重点解析了如何避免因直接导入CAD几何体导致的性能与精度问题,科学设置接触参数以提升计算效率与结果平滑度,以及通过规范的命名与组织管理模型,确保仿真过程高效可靠。

gin88的博客 573

【C++】哈希的应用:位图(bitset)和布隆过滤器(bloomfilter)

面对判断一个数在不在海量数据中的问题,红黑树和哈希表查找效率是挺高的,但是我们光把海量数据存起来够呛,同时红黑树和哈希表附带的内存消耗,所需空间更大,基于这样的原因,提出了位图这种数据结构。布隆过滤器(Bloom Filter)是由布隆在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,它的实现是一个「很长的二进制向量(位数组)」和「一系列哈希函数」。可以用来快速判断一个元素一定不存在或者可能存在一个集合中”。...

codewinter的博客 1279

腾讯滑块验证码collect参数逆向与JSVMP对抗实战

本文深入解析腾讯滑块验证码collect参数的逆向过程与JSVMP虚拟机对抗技术。通过详细的环境搭建、抓包分析和JSVMP逆向技巧,揭示collect参数的生成逻辑与加密流程,并提供完整的模拟实现方案和常见问题排查方法,助力开发者突破腾讯天御验证码的防护机制。

weixin_29009501的博客 1578

【C++】BitSet和Bloom_Filter

C++位图布隆过滤器

A.的博客 2246

覆冰监测系统服务器,基于分布式光纤振动传感的电缆覆冰舞动监测系统

监测意义我国高压输电网络已经形成了全国联网的格局,总规模世界第一。2018年底,全国发电装机容量已达19.0亿千瓦,全国 220kV及以上输电线路回路长度超过71万公里。我国电力能源集中在西北,而用户则集中在华东华南,所以高压输电网络的特点是长距离,大跨度,途径的自然环境多种多样。在高湿高寒的恶劣环境中,输电线非常容易发生覆冰舞动事故,由于覆冰形成的规则的非圆断面的缆线在风的激励下形成谐振,造成低...

weixin_32566055的博客 1547

第39步 深度学习图像识别:Inception V3建模(Tensorflow)

第39步 深度学习图像识别:Inception V3建模(Tensorflow)

Jet4505的博客 3168

使用Java的BitSet实现BloomFilter

使用Java的BitSet实现BloomFilter

诸葛小猿 455

C++怎么学?零基础也可以,一份完整学习路线图助你搞定!

提供一条清晰、系统且实践导向的C++学习路径。从基础语法、面向对象、泛型编程、异常处理,逐步深入STL、智能指针、并发编程等现代C++高级特性。无论是新手还是希望提升,通过系统学习与项目实践,助您将理论知识转化为实际解决问题的能力。

Lion_Long的博客 4027

布隆过滤器(Bloom Filter)详解,以及Java代码实现

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

masetLI的博客 5695

CryoEM - 冷冻电镜 基于深度学习的 从头重构(Ab-initio Reconstruction) 开源项目 教程

冷冻电镜(CryoEM) 是一种成像方式,为蛋白质和其他生命基本组成部分的动态,提供独特的观察方式。从数百万噪声和随机取向的二维投影中,以计算效率高的方式,联合估计生物大分子的姿态、三维结构和构象异质性。

AGI 1557

STM32 W5500 Freemodbus Modbus TCP协议功能实现

STM32F103VCT6 W5500(SPI1),实现Modbus-TCP协议的功能

坚韧与专注 2万+

Bloom Filter理解

解决的问题 1、BitSet/布隆过滤器: 大数据量的时候, 判断一个元素是否在一个集合中 2、计数布隆过滤器:大数据量的时候,针对元素进行计数 Bitset 原理 int => 4个字节 = 32位 long => 8个字节 = 64位 一个很长的二进制向量,每一个bit为初始为0 添加元素时,将这个元素index对应的位置为1 查询元素时,如果这个元素作为index对应位为...

weixin_42944192的博客 919

C#串口通信从入门到精通(11)——串口接收的数据存储到本地文件(txt、csv)

本文详细介绍如何将串口通信将数据进行本次存储,主要介绍常用的csv、txt格式文件,由多年实战经验总结,绝对干货!

qq_34059233的博客 7239

java bitset bitmap_BitMap、BitSet与Bloom Filter

推荐阅读时间:5分钟引言先来看一个问题,假设现在有范围为 1-10 亿的 11 亿个 int 型整数,如何排除掉其中的重复数字? int 占 4 个字节,可以表示 -2,147,483,648 ~ +2,147,483,647 的数据。 所以一般的思路是会将这 11 亿个数作为 int 型数据存到一个 HashSet 集合中进行去重。 但是,这样会存在一个问题。我们知道 1GB=1024KB=10...

weixin_39744316的博客 267

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

位图和布隆过滤器

构造一个16位的位图,所有位都初始化为0。构造一个16位的位图,根据所给值初始化位图的前n位。构造一个16位的位图,根据字符串中的0/1序列初始化位图的前n位。

脑袋空空的博客 928

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

深度解析Redisson Bloom Filter:分布式场景下的高性能过滤架构设计

Redisson Bloom Filter作为分布式系统中的关键概率型数据结构,为大规模数据处理提供了高效的元素存在性检测能力。本文将从架构原理、并发设计、性能优化到实战应用,全方位剖析这一分布式布隆过滤器的核心技术实现。 ## 架构原理深度剖析 ### 核心数据结构设计 Redisson Bloom Filter基于Redis的BitSet和Hash结构构建,实现了分布式的概率型集合。其核

gitblog_01191的博客 385

3种架构模式破解Redisson Bloom Filter并发读写性能瓶颈

在分布式系统中,你是否曾遭遇过Bloom Filter误判率飙升的诡异现象?或者在高并发场景下,明明元素已添加却返回"不存在"的缓存一致性问题?这些问题往往源于Redisson Bloom Filter在并发读写时的架构设计缺陷。本文将深度解析Redisson Bloom Filter的并发挑战,并提供3种实战架构方案,助你构建高性能、高可靠的分布式过滤系统。 ## 问题诊断:并发环境下的三大性

gitblog_00804的博客 733

<位图(bitset)和布隆过滤器(BloomFilter)>——《C++高阶》

哈希的应用、位图的模拟实现、布隆过滤器的模拟实现、海量数据处理等

m0_57859086的博客 1021

布隆过滤器介绍以及实现

1.什么是布隆过滤器(Bloom-Filter) 介绍:Bloom-Filter一般用于在大数据量的集合中判定某元素是否存在。 常用应用场景:当并发量很大并且无效请求较多时,很容易造成缓存击穿,使用布隆过滤器来过滤无效请求。 2.布隆过滤器实现原理。 布隆过滤器采用多个相互独立的hash函数,结合bit数组的底层数据结构,计算hash值。对hash结果对应的位置进行取值,假如有位置是0值则说明数据不存在。 比如: 优缺点:优点是空间效率和查询时间都远超过一般的算法,缺点是有一定的误识别率和.

qq_39094614的博客 329

Bloom filter(布隆过滤器)

问题: 假设要你写一个网络蜘蛛(web crawler)。由于网络间的链接错综复杂,蜘蛛在网络间爬行很可能会形成“环”。为了避免形成“环”,就需要知道蜘蛛已经访问过那些URL。给一个URL,怎样知道蜘蛛是否已经访问过呢?稍微想想,就会有如下几种方案: 1. 将访问过的URL保存到数据库。 2. 用HashSet将访问过的URL保存起来。那只需接近O(1)的代价就可以查到一个U

lizhihaoweiwei的专栏 752

布隆过滤器(Bloom Filter)详解

原文来源:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html                           http://www.cnblogs.com/heaad/archive/2011/01/02/1924195.html     布隆过滤器概念      (Bloom Filter)是由布隆(B

leehbing的博客 636

布隆过滤器(Bloom Filter)基础知识

布隆过滤器(Bloom Filter)基础知识   布隆过滤器 (Bloom Filter)是由Burton Howard Bloom于1970年提出,它是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。在网页黑名单系统、垃圾邮件过滤的黑白名单方法、爬虫(Crawler)的网址判重模块中等等经常被用到。哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希

菜鸟闯天下的专栏 867

Bloom Filter布隆过滤器(解决redis缓存穿透)

1.布隆过滤器: 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。 如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定,链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢。 比如: 链表O(n), 树O

MrYushiwen的博客 6223

爬虫教程( 6 ) --- CrawlSpider、RedisCrawlSpider、Bloom Filter

追踪(CrawlSpider)、过滤(布隆过滤)、去重、解析

freeking101的博客 6560
上一篇: 生产服务器环境最小化安装后 Centos 6.5优化配置备忘
下一篇: Memcached之缓存雪崩,缓存穿透,缓存预热,缓存算法(7)
qianshanding0708
博客等级 码龄11年 427粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值