是什么:
判断某个数据是否在大数据量集合中,并且不占内存
它可以告诉你某种东西一定不存在或者可能存在。
能干什么:
1 之前爬过100万个url ,判断url是否爬取过?
2 有10亿个电话,判断某个号码是否在这10亿个中?
4解决缓存穿透 把已经存在的key放到布隆过滤器里,如果用布隆过滤器查询没有就直接返回没有,如果有就是可能有,就算通过,能大大减少数据库并发
原理:
有2个主要方法,放入和查询。
1 放入过滤器数据,数据会进行多次hash 然后hash节点对应的结果 标注为1,如果已经是1就还是1
2 查询:使用查询的值进行多次hash,如果对应的hash位置都是1 那就有可能有,如果有一个不是1就一定没有(有可能有是因为数据量大,hash的多导致坑都被占)
其他点:
1 布隆过滤器不能删除已经放进去的节点,因为有可能已经叠加了,会破坏过滤器功能
2 布隆过滤器不能扩容,因为他节省空间的优势,所以没有元数据,hash数据结果不可逆,所以不能扩容,这里如果扩容方案就是,新建一个更大的布隆过滤器,新的数据添加到新的过滤器上,两个过滤器一起用。
java代码:
package 算法;
import java.util.ArrayList;
import java.util.List;
public class 布隆过滤器 {
//布隆过滤器(Bloom Filter)详解
public static class BloomFilter {
int[] bloomArr;
int limit;
//hash次数
int hashSize = 4;
List<String> list;
/**
* 初始化布隆大小
*
* @param size
*/
public BloomFilter(int size) {
limit = size;
this.bloomArr = new int[size];
list = new ArrayList<>();
list.add("asdf");
list.add("hgjk");
list.add("dsaf");
list.add("grgrg");
}
/**
* 放入数据
*
* @param value
*/
public void put(String value) {
for (int i = 0; i < hashSize; i++) {
int j = getHash(value + list.get(i));
bloomArr[j] = 1;
}
}
/**
* 判断数据是否在
* ture 不一定存在
* false 一定不存在
*
* @param value
*/
public boolean exist(String value) {
for (int i = 0; i < hashSize; i++) {
int j = getHash(value + i);
if (bloomArr[j] == 0) {
return false;
}
}
return true;
}
private int getHash(String value) {
return toAbs(value.hashCode() % limit);
}
//取绝对值方法
//int类型存入是以二进制补码的形式在内存中,要取绝对值,只需要改变其符号位
public int toAbs(int n) {
int i = n >> 31; //int 为32位,右移31位得到符号位,赋值给i,若为正,则i==0;负,i==-1
return ((n ^ i) - i); //一个数^0==原数,数^-1==数的绝对值-1 ==》 绝对值=负数异或-1取反+1
}
}
public static void main(String[] args) {
//创建
BloomFilter bloomFilter = new BloomFilter(100);
bloomFilter.put("chenchen");
bloomFilter.put("超人");
bloomFilter.put("蜘蛛侠");
bloomFilter.put("钢铁侠");
bloomFilter.put("咸蛋超人");
//判断验证
List<String> list = new ArrayList<>();
list.add("chenchen");
list.add("咸蛋超人");
list.add("123");
list.add("555");
for (String s : list) {
if (bloomFilter.exist(s)) {
System.out.println(s + ":有可能有");
} else {
System.out.println(s + ":一定没有");
}
}
}
}