正好在“问答”和“论坛”中看到关于Bloom Filter的帖子,学习研究了一把,自娱自乐就写了一种实现。不多说,直接上代码,代码尽量写得具备可读性,不多解释了。关于Bloom Filter可以参考
http://www.google.com.hk/ggblog/googlechinablog/2007/07/bloom-filter_7469.html
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.BitSet;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class BloomFilter<T extends Serializable> implements Serializable {
/**
*
*/
private static final long serialVersionUID = -4322599722288348992L;
private static final int DEFAULT_CAPACITY = 1 << 16;
private transient BitSet filter;
private HashGenerator<T> hashGenerator;
private int hashSize;
private int nbits;
public BloomFilter(HashGenerator<T> hashGenerator) {
this(hashGenerator, hashGenerator.size(), DEFAULT_CAPACITY);
}
public BloomFilter(HashGenerator<T> hashGenerator, int capacity) {
this(hashGenerator, hashGenerator.size(), capacity);
}
public BloomFilter(HashGenerator<T> hashGenerator, int hashSize, int capacity) {
super();
this.hashGenerator = hashGenerator;
this.hashSize = hashSize;
this.nbits = capacity * hashSize * 2;
filter = new BitSet(nbits);
}
private void writeObject(ObjectOutputStream out) throws IOException {
// 压缩
ByteArrayOutputStream buf = new ByteArrayOutputStream();
ObjectOutputStream objOut = new ObjectOutputStream(new GZIPOutputStream(buf));
objOut.writeObject(filter);
objOut.close();
out.writeObject(buf.toByteArray());
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
byte[] buf = (byte[]) in.readObject();
ObjectInputStream objIn = new ObjectInputStream(new GZIPInputStream(
new ByteArrayInputStream(buf)));
filter = (BitSet) objIn.readObject();
objIn.close();
in.defaultReadObject();
}
public void add(T key) {
for (int i = 0; i < hashSize; i++) {
long hashCode = hashGenerator.getHashCode(key, i);
int index = hashGenerator.getBitIndex(hashCode, nbits);
filter.set(index);
}
}
public boolean contains(T key) {
for (int i = 0; i < hashSize; i++) {
long hashCode = hashGenerator.getHashCode(key, i);
int index = hashGenerator.getBitIndex(hashCode, nbits);
if (!filter.get(index))
return false;
}
return true;
}
}
import java.io.Serializable;
public interface HashGenerator<T> extends Serializable {
public int getBitIndex(long hashCode,int maxIndex);
public long getHashCode(T key, int index);
public int size();
}
import java.util.Random;
public abstract class AbstractHashGenerator<T> implements HashGenerator<T> {
/**
*
*/
private static final long serialVersionUID = 1918866698987940799L;
private static final Random rand = new Random();
private int size;
public AbstractHashGenerator(int size) {
super();
this.size = size;
}
public int getBitIndex(long hashCode, int maxIndex) {
rand.setSeed(hashCode);
return rand.nextInt(maxIndex);
}
public int size() {
return size;
}
}
public class SimpleHashGenerator<T> extends AbstractHashGenerator<T> {
/**
*
*/
private static final long serialVersionUID = -6971076063651082178L;
public SimpleHashGenerator(int size) {
super(size);
}
public SimpleHashGenerator() {
this(8);
}
private long getHashCode2(T key, int index) {
int h = index * key.hashCode();
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
private long getHashCode1(T key, int index) {
int h = index * 31 + key.hashCode();
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}
public long getHashCode(T key, int index) {
return getHashCode1(key, index);
// return getHashCode2(key, index);
// if ((index & 1) == 0) {
// return getHashCode1(key, index);
// } else {
// return getHashCode2(key, index);
// }
}
}
小小测试:
import java.io.File;
import java.io.Serializable;
import bluechip.io.SerializeUtils;
public class BloomFilterTest {
static class Key implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7503732767154152820L;
String name;
String id;
public Key(String name, String id) {
super();
this.name = name;
this.id = id;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Key other = (Key) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Key [id=" + id + ", name=" + name + "]";
}
}
/**
* @param args
*/
public static void main(String[] args) throws Exception {
File file = new File("d:/filter.dat");
int n = 1000000;
BloomFilter<Key> bf = null;
try {
bf = SerializeUtils.readObject(file);
} catch (Exception ex) {
bf = new BloomFilter<Key>(new SimpleHashGenerator<Key>(), n);
for (int i = 0; i < n; i++) {
bf.add(new Key("Jim", String.valueOf(i)));
}
SerializeUtils.writeObject(bf, new File("d:/filter.dat"));
}
System.out.println("==================");
for (int i = 0; i < n; i++) {
Key k = new Key("aaa", String.valueOf(i));
if (bf.contains(k)) {
System.out.println(k);
}
}
System.out.println("==================");
for (int i = 0; i < n; i++) {
Key k = new Key("Jim", String.valueOf(i));
if (!bf.contains(k)) {
System.out.println(k);
}
}
}
}
分享到:
相关推荐
Java-BloomFilter, 在Java中,一个独立的Bloom过滤器 java-bloomfilterJava bloomfilter是一个独立于Java的Bloom过滤器实现。 它旨在在不需要额外库开销的情况下包含在现有项目中。 第一个版本是由 Ian的博客条目...
Java 中实现布隆过滤器,通常可以使用开源库Guava提供的`com.google.common.hash.BloomFilter`类。Guava的布隆过滤器提供了灵活的参数配置,包括期望元素数量(expectedInsertions)和错误率(fpp,False Positive ...
在Java中,我们可以使用Guava库中的`com.google.common.hash.BloomFilter`类来实现Bloom Filter。Guava提供了几个预定义的哈希函数组合,可以自动调整位数组的大小和哈希函数的数量以达到目标误判率。 ```java ...
在Java中实现Bloom Filter,我们通常会用到位数组(Bit Array)和几个不同的哈希函数。位数组是一组二进制位,可以理解为一个很长的数字,其中每个位代表一个可能的元素。哈希函数则将输入映射到这个位数组的特定...
首先,Bloom Filter是一种概率型数据结构,通过使用多个哈希函数将元素映射到位数组中。尽管它能高效地判断一个元素可能不存在于集合中,但可能会产生误报(False Positives),即报告一个实际上不在集合中的元素为...
具有JSON(反)序列化和(zlib)压缩的Java Bloomfilter实现 您可以在此处找到兼容的PYTHON实现: : 例子: BloomFilter bf1 = new BloomFilter(1000000, 0.001); bf1.add("Alabama"); bf1.add("Illinois"); bf1...
在Java中,可以使用开源库如Guava提供的BloomFilter类来实现。首先,需要创建一个BloomFilter实例,指定预期的元素数量和错误率。错误率通常是一个较小的浮点数,如0.01,表示1%的误判率。Guava的BloomFilter构造器...
在Java中实现布隆过滤器,可以使用Guava库提供的`com.google.common.hash.BloomFilter`类。Guava的BloomFilter提供了创建、添加元素和查询元素的方法,并且支持动态调整过滤器的大小以控制误判率。以下是一个简单的...
布隆过滤器实现 为 Java SE 8 计算 BloomFilter。用法 // capacity: 1000, error_rate: 0.001(= 0.1%)final BloomFilter<String> bf1 = new BloomFilter<>(1000, 0.01);bf.add("test");bf.contains("test"); // =...
This is the bloom filter of 2.5 Million ... BloomFilter bf=new BloomFilter(); BitSet bitSet=bf.readBit(fileName); bf.setBits(bitSet); System.out.println(bf.exist("password")); } it will says true.
redis-bloomFilter是基于redis的bitset实现的bloomfilter.具体原理和实现思路可以参考 使用 redis-bloomFilter发布在JitPack,可以选择下载源码编译,或者通过jitpack源添加依赖。 使用Maven添加依赖 添加jitpack源 ...
提出的解决方案是用Java实现的。 Python实现可。 它包含几种用于生成独立哈希函数的方法: 双重散列 三重哈希 增强型双散列 Peter C. Dillinger和Panagiotis Manolios的“概率验证中的布鲁姆过滤器”中介绍了所有...
布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。在Java开发中,特别是在处理大数据、内存限制或需要快速查询是否存在某个元素的场景下,布隆过滤器是一个...
例如,Python中的`pybloom`库,Java中的`Guava`库都提供了Bloom Filter的实现。 通过学习提供的9个PPT和PDF文档,你可以深入了解Bloom Filter的工作机制、性能分析以及在不同场景下的应用实例,从而更好地理解和...
自己写的Java抓图程序 原理见 http://blog.csdn.net/binyao02123202/archive/2010/07/12/5728840.aspx 用了序列化 线程 和BloomFilter算法
【布隆过滤器(Bloom Filter)的Java实现】 布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。它可能会产生误报(false positive),但不会产生漏报(false negative)。在Java...
var BloomFilter = require('bloom-filter'); var bf = new BloomFilter({ elements: [1, 2, 3], p: 0.001 // default value of false positive rate }); bf.has(1) // true 原料药 建设者 BloomFilter(opts) ...
在处理"相似项发现"问题时,这三个技术常常结合使用:首先使用`shingling`将原始数据转化为shingles,然后通过`simhash`计算每个数据项的哈希值,最后利用`bloom filter`快速判断两个数据项是否可能相似。...
Magnus Skjegstad从Java实现中移植的内容:https://github.com/MagnusS/Java-BloomFilter Bloom过滤器是一种数据结构,旨在快速且高效地告知您元素是否存在于集合中。 它是一个概率数据结构:虽然可以肯定地告诉您...