当Guava项目发布版本11.0时,新添加的功能之一是BloomFilter类。 BloomFilter是唯一的数据结构,用于指示元素是否包含在集合中。 使BloomFilter有趣的是,它将指示元素是否绝对不包含或可能包含在集合中。
永远不会出现假阴性的特性使BloomFilter成为用作保护条件的绝佳候选者,以帮助防止执行不必要和昂贵的操作。 虽然BloomFilters最近获得了很好的曝光,但使用它意味着滚动自己的浏览器或通过Google搜索代码。 滚动自己的BloomFilter的麻烦在于获取正确的哈希函数来制作过滤器
有效。 考虑到Guava使用Murmur Hash来实现,我们现在有一个有效的BloomFilter有用,而只是一个图书馆而已。
BloomFilter速成课程
BloomFilters本质上是位向量。 在较高级别,BloomFilters以下列方式工作:
- 将元素添加到过滤器。
- 将其哈希几次,然后将索引与哈希结果匹配的位设置为1。
测试元素是否在集合中时,请遵循相同的哈希过程,并检查这些位是否设置为1或0。此过程是BloomFilter如何保证元素不存在的方法。 如果未设置位,则根本不可能将元素包含在集合中。 但是,肯定答案表示元素在集合中或发生哈希冲突。 可以在此处找到BloomFilter的更详细描述,并在此处找到有关BloomFilters的良好教程。 根据Wikipedia的说法,Google在BigTable中使用BloomFilters来避免对不存在的项目进行磁盘查找。 另一个有趣的用法是使用BloomFilter来优化sql Querry 。
使用番石榴BloomFilter
通过调用BloomFilter类上的static方法create来创建Guava BloomFilter,
传递一个Funnel对象和一个int表示预期的插入次数。 漏斗也是Guava 11中的新功能,它是一个可以将数据发送到Sink的对象。 下面的示例是默认实现,其误报百分比为3%。 Guava提供了一个Funnels类,其中包含两个静态方法,这些方法提供Funnel接口的实现,用于将CharSequence或字节数组插入到过滤器中。
//Creating the BloomFilter
BloomFilter bloomFilter = BloomFilter.create(Funnels.byteArrayFunnel(), 1000);//Putting elements into the filter
//A BigInteger representing a key of some sort
bloomFilter.put(bigInteger.toByteArray());//Testing for element in set
boolean mayBeContained = bloomFilter.mayContain(bitIntegerII.toByteArray());
更新:基于路易斯·沃瑟曼的评论,以下是如何使用自定义Funnel实现为BigIntegers创建BloomFilter的方法:
//Create the custom filter
class BigIntegerFunnel implements Funnel<BigInteger> {@Overridepublic void funnel(BigInteger from, Sink into) {into.putBytes(from.toByteArray());}}//Creating the BloomFilter
BloomFilter bloomFilter = BloomFilter.create(new BigIntegerFunnel(), 1000);//Putting elements into the filter
//A BigInteger representing a key of some sort
bloomFilter.put(bigInteger);//Testing for element in set
boolean mayBeContained = bloomFilter.mayContain(bitIntegerII);
注意事项
正确估计预期插入的数量至关重要。 当插入过滤器的次数接近或超过预期的数目时,BloomFilter开始填满,结果将产生更多的误报,直至无用之地。 还有另一个版本的BloomFilter.create方法,该方法带有一个附加参数,双精度表示所需的错误命中概率级别(必须大于0且小于1)。 错误命中概率的级别会影响用于存储或搜索元素的哈希数。 所需的百分比越低,执行的哈希数越高。
结论
BloomFilter是开发人员可以在其工具箱中使用的有用项。 现在,Guava项目使在需要时开始使用BloomFilter变得非常简单。 希望您喜欢这篇文章。 欢迎提出有用的意见和建议。
参考文献
- Guava BloomFilter的单元测试演示 。
- BloomFilter类
- 您想了解的所有关于BloomFilters的信息 。
- BloomFilter教程 。
- Wikipedia上的BloomFilter 。
参考:来自我们的JCG合作伙伴 Bill Bejeck的Google Guava BloomFIlter,来自“ 随机思考编码”博客。
翻译自: https://www.javacodegeeks.com/2012/12/google-guava-bloomfilter.html