1.一般Bloom过滤器
一.什么是Bloom过滤器?
其原理是:
1.当一个元素被加入集合,通过K个hash函数将这个元素映射为一个位数组中的K个点,把他们置为1。
2.检索时,我们只需要查看我们需要判断的元素通过hash函数计算映射到的这些点是不是都是1来判断:若都为1,则说明可能存在(存在交叉映射的可能)。但只要有一个为0,则一定不存在。
优点:它的存储空间和插入/查询时间都是常数,很快。
缺点:数据集里的元素越多,误判率越大。
二.java代码实现
package Bloom过滤器;
import java.util.BitSet;
public class Bloom {
private static final int BIT_SIZE = 2 << 29;
private static final int[] seeds = new int[]{3, 5, 7, 13, 31, 37, 61};//用于生成信息指纹的8个随机数
private BitSet bits = new BitSet(BIT_SIZE);//BitSet类大小可动态改变, 取值为true或false的位集合。用于表示一组布尔标志。
private Hash[] func = new Hash[seeds.length];//存储8个哈希值对象
public Bloom() {//构造方法
for (int i = 0; i < seeds.length; i++) {
func[i] = new Hash(BIT_SIZE, seeds[i]);//构造8个哈希对象
}
}
public void addValue(String value)//将字符串value哈希为8个数,然后在这些整数的bit上变为1
{
if(value!=null)
{
for(Hash f:func)//循环变量f依次取func[]中的值
bits.set(f.hash(value),true);//将哈希值位置置为1
}
}
public boolean contains(String value)//筛选过滤
{
if(value==null)
return false;
boolean ret=true;
//将要比较的字符串重新以上述方法计算hash值,再与bloom过滤器对比
for(Hash f:func)
{
ret=ret&& bits.get(f.hash(value));
}
return ret;
}
//随机哈希值对象定义
public static class Hash{
private int size;//二进制向量数组大小
private int seed;//随机数种子
//构造方法
public Hash(int cap,int seed){
this.size=cap;
this.seed=seed;
}
//计算哈希值
public int hash(String value)
{
int result=0;
int len=value.length();
for(int i=0;i<len;i++)
{
result=seed*result+value.charAt(i);//str.charAt(i)的意思是第i个字符的asc码,输出的是数字
}
//System.out.println((size-1)&(result));
return (size-1)&result;//返回哈希值
}
}
public static void main(String[] args) {
Bloom b=new Bloom();
b.addValue("www.baidu.com");
b.addValue("www.csdn.com");
System.out.println(b.contains("www.gass.com"));
System.out.println(b.contains("www.baidu.com"));
}
}
结果: