布隆过滤器
- 布隆过滤器
Bloom Filter
,是1970年由布隆提出的;它实际上是一个很长的二进制向量(BitMap)
和一系列随机映射函数
- 可以用于
检索一个元素是否在一个集合中
- 优点:
空间效率
和查询时间
都很好 - 缺点:有一定的
误识别率
和删除困难
,通常是只增/查不删 - 原理:当一个元素被加入集合时,通过
k个散列函数
将这个元素映射成一个位数组中的k个点
,把他们设置为1;检索时,我们只要看这些点是不是都是1就可以大约知道
集合中是否有这个值,只要存在一个点不为1,则被检测的元素一定不存在,若全为1,则认为元素很可能存在
- 代码实现
public class BloomFilter {
private static final int NumSlots = 1024 * 1024 * 8;
private static final int NumHash = 8;
private BigInteger bitmap = new BigInteger("0");
public void addElement(String message){
for (int i = 0; i < NumHash; i++) {
int hashCode = getHash(message, i);
if(!bitmap.testBit(hashCode)){
bitmap = bitmap.or(new BigInteger("1").shiftLeft(hashCode));
}
}
}
private int getHash(String message, int n){
message = message + n;
try {
MessageDigest md5 = MessageDigest.getInstance("md5");
byte[] bytes = message.getBytes();
md5.update(bytes);
BigInteger bi = new BigInteger(md5.digest());
return Math.abs(bi.intValue())%NumSlots;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return -1;
}
public boolean check(String message){
for (int i = 0; i < NumHash; i++) {
if(!this.bitmap.testBit(getHash(message, i))){
return false;
}
}
return true;
}
public static void main(String[] args) {
BloomFilter bloomFilter = new BloomFilter();
Random random = new Random();
bloomFilter.addElement("123456");
for (int i = 0; i < 1000; i++) {
bloomFilter.addElement(i*8*(i-1) + random.nextInt(1000) + "");
}
System.out.println(bloomFilter.check("123456"));
System.out.println(bloomFilter.check("1236"));
System.out.println(bloomFilter.check("13579242356547"));
}
}