`
chen_yongkai
  • 浏览: 61946 次
  • 性别: Icon_minigender_1
  • 来自: 福州
文章分类
社区版块
存档分类
最新评论

用Java实现Bloom Filter

阅读更多
正好在“问答”和“论坛”中看到关于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);
			}
		}
	}

}
分享到:
评论
4 楼 wa114d 2012-08-30  
牛人啊 能提供代码jar包吗
3 楼 happyITLife 2012-06-05  
hj01kkk 写道
你的这个类在哪里定义的?bluechip.io.SerializeUtils,方便提供下不?

同问,不知道导入哪个jar
2 楼 chen_yongkai 2012-05-28  
	@SuppressWarnings("unchecked")
	public static <T> T readObject(File src) throws IOException, ClassNotFoundException {
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(src)));
			return (T) ois.readObject();
		} finally {
			IOUtils.close(ois);
		}
	}


	public static void writeObject(Object obj, File file) throws FileNotFoundException, IOException {
		if (obj == null)
			throw new NullPointerException("obj are null.");
		ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(
				new FileOutputStream(file)));
		try {
			oos.writeObject(obj);
		} finally {
			IOUtils.close(oos);
		}
	}
1 楼 hj01kkk 2012-05-28  
你的这个类在哪里定义的?bluechip.io.SerializeUtils,方便提供下不?

相关推荐

    Java-BloomFilter, 在Java中,一个独立的Bloom过滤器.zip

    Java-BloomFilter, 在Java中,一个独立的Bloom过滤器 java-bloomfilterJava bloomfilter是一个独立于Java的Bloom过滤器实现。 它旨在在不需要额外库开销的情况下包含在现有项目中。 第一个版本是由 Ian的博客条目...

    java-bloomfilter

    Java 中实现布隆过滤器,通常可以使用开源库Guava提供的`com.google.common.hash.BloomFilter`类。Guava的布隆过滤器提供了灵活的参数配置,包括期望元素数量(expectedInsertions)和错误率(fpp,False Positive ...

    Java版本的BloomFilter (布隆过滤器)

    在Java中,我们可以使用Guava库中的`com.google.common.hash.BloomFilter`类来实现Bloom Filter。Guava提供了几个预定义的哈希函数组合,可以自动调整位数组的大小和哈希函数的数量以达到目标误判率。 ```java ...

    Bloom-Filter:Java中Bloom Filter数据结构的实现

    在Java中实现Bloom Filter,我们通常会用到位数组(Bit Array)和几个不同的哈希函数。位数组是一组二进制位,可以理解为一个很长的数字,其中每个位代表一个可能的元素。哈希函数则将输入映射到这个位数组的特定...

    Go-Go中的CuckooFilter实现比BloomFilter更好

    首先,Bloom Filter是一种概率型数据结构,通过使用多个哈希函数将元素映射到位数组中。尽管它能高效地判断一个元素可能不存在于集合中,但可能会产生误报(False Positives),即报告一个实际上不在集合中的元素为...

    java-bloomfilter:具有JSON(反)序列化和(zlib)压缩的Java Bloomfilter实现

    具有JSON(反)序列化和(zlib)压缩的Java Bloomfilter实现 您可以在此处找到兼容的PYTHON实现: : 例子: BloomFilter bf1 = new BloomFilter(1000000, 0.001); bf1.add("Alabama"); bf1.add("Illinois"); bf1...

    如何使用bloomfilter构建大型Java缓存系统Ja

    在Java中,可以使用开源库如Guava提供的BloomFilter类来实现。首先,需要创建一个BloomFilter实例,指定预期的元素数量和错误率。错误率通常是一个较小的浮点数,如0.01,表示1%的误判率。Guava的BloomFilter构造器...

    bloom-filter:Java中Bloom过滤器的实现

    在Java中实现布隆过滤器,可以使用Guava库提供的`com.google.common.hash.BloomFilter`类。Guava的BloomFilter提供了创建、添加元素和查询元素的方法,并且支持动态调整过滤器的大小以控制误判率。以下是一个简单的...

    java-bloomfilter:Java SE 8 的 BloomFilter 计数

    布隆过滤器实现 为 Java SE 8 计算 BloomFilter。用法 // capacity: 1000, error_rate: 0.001(= 0.1%)final BloomFilter&lt;String&gt; bf1 = new BloomFilter&lt;&gt;(1000, 0.01);bf.add("test");bf.contains("test"); // =...

    Bloom Filter of 2.5 Million common passwords

    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.

    javabitset源码-redis-bloomfilter:基于Redis的BloomfilterforJava

    redis-bloomFilter是基于redis的bitset实现的bloomfilter.具体原理和实现思路可以参考 使用 redis-bloomFilter发布在JitPack,可以选择下载源码编译,或者通过jitpack源添加依赖。 使用Maven添加依赖 添加jitpack源 ...

    BloomFilter-Java:Bloom过滤器的实现(双重哈希,三次哈希,增强型双重哈希)

    提出的解决方案是用Java实现的。 Python实现可。 它包含几种用于生成独立哈希函数的方法: 双重散列 三重哈希 增强型双散列 Peter C. Dillinger和Panagiotis Manolios的“概率验证中的布鲁姆过滤器”中介绍了所有...

    布隆过滤器BloomFilters的一个简单Java库

    布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。在Java开发中,特别是在处理大数据、内存限制或需要快速查询是否存在某个元素的场景下,布隆过滤器是一个...

    介绍Bloom Filter(布隆过滤器)原理、实现及具体应用

    例如,Python中的`pybloom`库,Java中的`Guava`库都提供了Bloom Filter的实现。 通过学习提供的9个PPT和PDF文档,你可以深入了解Bloom Filter的工作机制、性能分析以及在不同场景下的应用实例,从而更好地理解和...

    自己写的Java抓图程序(用了BloomFilter算法)

    自己写的Java抓图程序 原理见 http://blog.csdn.net/binyao02123202/archive/2010/07/12/5728840.aspx 用了序列化 线程 和BloomFilter算法

    布隆过滤器(Bloom Filter)的Java实现方法

    【布隆过滤器(Bloom Filter)的Java实现】 布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。它可能会产生误报(false positive),但不会产生漏报(false negative)。在Java...

    bloom-filter:Java语言的Bloom Bloom筛选器

    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、simhash、bloom filter

    在处理"相似项发现"问题时,这三个技术常常结合使用:首先使用`shingling`将原始数据转化为shingles,然后通过`simhash`计算每个数据项的哈希值,最后利用`bloom filter`快速判断两个数据项是否可能相似。...

    BloomFilter .NET:BloomFilter .NET-Bloom Filter的.NET实现-开源

    Magnus Skjegstad从Java实现中移植的内容:https://github.com/MagnusS/Java-BloomFilter Bloom过滤器是一种数据结构,旨在快速且高效地告知您元素是否存在于集合中。 它是一个概率数据结构:虽然可以肯定地告诉您...

Global site tag (gtag.js) - Google Analytics