Bitmap和Bloom Filiter(布隆过滤器)

一、Bitmap

Bitmap顾名思义,就是用bit来实现map的存储。

底层用map来实现对数据的存储,其使用一个bit位来标记某个元素的value,而key就是该元素。

举例:
以下的map就表示{1,2,4,6}这四个数
在这里插入图片描述
我们知道一个字节是8位,那如果要表示的数字超过了7,比如{12,13,15}该如何表示呢?
其实只需要再开辟一个字节的map即可,如下图:
在这里插入图片描述
同理,我们可以用这种类似二维数组的表示法表示任意数字!!!
并且,给定任意整数M,那么M/32就得到下标,M%32就知道它在此下标的哪个位置

优点:

最大的优点就是存储空间小,一个字节8个bit,如果是一个int数字,在java中是4个字节
那么存储40亿个数,则使用字节存储所用空间为: (4000000000*4/1024/1024/1024)≈14.90G
如果使用bitmap,则为:(4000000000/8/1024/1024/1024)≈0.466G
这个空间省得就显而易见了。

缺点:

当数据中有重复数据时,便很难用这种数据结构进行存储。
如果数据不是很集中,便需要跨多个map进行搜索,效率不高

Bloom Filiter-----布隆过滤器

Bloom filter 是一个数据结构,它可以用来判断某个元素是否在集合内,是Bitmap的具体应用,具有运行快速,内存占用小的特点。

而高效插入和查询的代价就是,Bloom Filter 是一个基于概率的数据结构:它只能告诉我们一个元素绝对不在集合内或可能在集合内

BloomFilter 流程

1.首先需要 k 个 hash 函数,每个函数可以把 key 散列成为 1 个整数;

2.初始化时,需要一个长度为 n 比特的数组,每个比特位初始化为 0;

3.某个 key 加入集合时,用 k 个 hash 函数计算出 k 个散列值,并把数组中对应的比特位置为 1;

4.判断某个 key 是否在集合时,用 k 个 hash 函数计算出 k 个散列值,并查询数组中对应的比特位,如果所有的比特位都是1,认为在集合中。
在这里插入图片描述

应用

主要应用于大规模数据下不需要精确过滤的场景,如:
检查垃圾邮件地址,爬虫URL地址去重,解决缓存穿透问题等

例如检查垃圾邮件地址:
我们知道hash函数的时间复杂度为O(1),那么我们就不用将该邮件地址,和垃圾邮件地址一个个去循环遍历比对,只需要通过hash函数计算出该地址所在的各个数组位,看是否有和某个垃圾邮件的数组位一样,是则为垃圾邮件。

优点:

快速,节省空间。

缺点

不精确,即使使用多个hash函数重复确认,但还是可能造成冲突的问题。