这里写自定义目录标题
想要理解Bloom Filter,其实最好想理解BitMap,这里有一个非常好的帖子 理解bitmap,这个帖子浏览了一下好像没看到如何把对应位置置为1,我给大家示范一下,仅供参考
//比如我要存储10000个URl做黑名单 那么只需要开10000/64 (long 64个bit位) 的long数组
long[] longs = new long[1 + 10000 / 64]; //大家思考一下为啥加1
//对www.baidu.com取hash值再模100000为 34,那么应该放入哪个下标的数组呢
//应该是 longs[0] 因为 34/64=0
//那应该放在long[0]的哪个位置呢 答案是 34%64
//那么问题来了 如何将long[0]的第34为变为1呢
//很简单 1<<34位,然后和long[0]或 如下图 举一个8位的例子
// long[0]=0 0 0 0 0 0 0 0 0
// 1 0 0 0 0 0 0 0 1 1左移2位-》 0 0 0 0 0 1 0 0
//然后 做或运算 long[0]=0 0 0 0 0 0 0 0 0
// 0 0 0 0 0 1 0 0
// 结果 0 0 0 0 0 1 0 0 这样 对应位置就变为le 我猜测这就是java bitset的原理
然乎java里BitSet实现了BitMap这个结构
这里借助bitset实现了一个标准的布隆过滤器
/**
**/
public class BloomFilter {
//hash函数
class HashFunction {
public int cap, seed;
public HashFunction(int cap, int seed) {
this.cap = cap;
this.seed = seed;
}
public int hash(String value) {
int ret = 0;
int n = value.length();
for (int i = 0; i < n; ++i) {
ret += seed * ret + value.charAt(i);
ret %= cap;
}
return ret;
}
}
public class StandardBloomFilter {
public BitSet bits;
public int k;//k个hash函数 原理可以百度一下
public List<HashFunction> hashFunc;
public StandardBloomFilter(int k) {
this.k = k;
hashFunc = new ArrayList<HashFunction>();
for (int i = 0; i < k; ++i)
hashFunc.add(new HashFunction(100000 + i, 2 * i + 3));//10000只是当初为了过oj,seed最好为质数
bits = new BitSet(100000 + k);
}
public void add(String word) {
for (int i = 0; i < k; ++i) {
int position = hashFunc.get(i).hash(word);
bits.set(position);
}
}
public boolean contains(String word) {
for (int i = 0; i < k; ++i) {
int position = hashFunc.get(i).hash(word);
if (!bits.get(position))
return false;
}
return true;
}
}
看看其他的Bloom fliter的文章再来看我的代码就还理解多了
不懂可以交流哦!