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

布隆过滤器原理很简单:就是把一个字符串哈希成一个整数key,然后选取一个很长的比特序列,开始都是0,在key把此位置的0变为1;下次进来一个字符串,哈希之后的值key,如果在此比特位上的值也是1,那么就说明这个字符串存在了。

如果按照上面的做法,那就和哈希算法没有什么区别了,哈希算法还有重复的呢。

布隆过滤器是将一个字符串哈希成多个key,我还是按照书上的说吧。

先建立一个16亿二进制常量,然后将这16亿个二进制位全部置0。对于每个字符串,用8个不同的随机产生器(F1,F2,.....,F8)产生8个信息指纹(f1,f2,....,f8).再用一个随机数产生器G把这八个信息指纹映射到1到16亿中的8个自然数g1,g2,...,g8。现在把这8个位置的二进制位全部变为1。这样一个布隆过滤器就建好了。

那么如何检测一个字符串是否已经存在了呢?

现在用8个随机数产生器(F1,F2,...,F8)对这个字符串产生8个信息指纹s1,s2,...,s8,然后将这8个信息指纹对应到布隆过滤器的8个二进制位,分别是T1,T2,...,T8.如果字符串存在,那么显然T1,T2,...,T8对应的二进制位都应该是1。就是这样来判断字符串是否已经存在的。

其实布隆过滤器就是对哈希算法的一个扩展,既然本质是哈希,那么就肯定会有不足,也就是说,肯定会有误判,一个字符串明明没有出现过而布隆过滤器判断出现了,虽然可能性很小,但是确实存在。

那么如何减少这种概率呢,首先可以想到的是如果将8个信息指纹扩展到16个错误的概率肯定会降低,但是也要考虑到,这样的话,那么一个布隆过滤器所能存储的字符串数量也降低了1倍;另外就是选取很好的哈希函数,对字符串的哈希方法有很多种,其中不乏很好的哈希函数。

布隆过滤器主要运用在过滤恶意网址用的,将所有的恶意网址建立在一个布隆过滤器上,然后对用户的访问的网址进行检测,如果在恶意网址中那么就通知用户。这样的话,我们还可以对一些常出现判断错误的网址设定一个白名单,然后对出现判断存在的网址再和白名单中的网址进行匹配,如果在白名单中,那么就放行。当然这个白名单不能太大,也不会太大,布隆过滤器错误的概率是很小的。有兴趣的读者可以去查阅,布隆过滤器的错误率。

下面给出Java版的布隆过滤器源码:

import java.util.BitSet; 

/**
 *
 * @author xkey
 */
public class BloomFilter { 

  private static final int DEFAULT_SIZE = 2 << 24;//布隆过滤器的比特长度
  private static final int[] seeds = {3,5,7, 11, 13, 31, 37, 61};//这里要选取质数,能很好的降低错误率
  private static BitSet bits = new BitSet(DEFAULT_SIZE);
  private static SimpleHash[] func = new SimpleHash[seeds.length]; 

  public static void addValue(String value)
  {
    for(SimpleHash f : func)//将字符串value哈希为8个或多个整数,然后在这些整数的bit上变为1
      bits.set(f.hash(value),true);
  } 

  public static void add(String value)
  {
    if(value != null) addValue(value);
  } 

  public static boolean contains(String value)
  {
    if(value == null) return false;
    boolean ret = true;
    for(SimpleHash f : func)//这里其实没必要全部跑完,只要一次ret==false那么就不包含这个字符串
      ret = ret && bits.get(f.hash(value));
    return ret;
  } 

  public static void main(String[] args) {
    String value = "www.jb51.net";
    for (int i = 0; i < seeds.length; i++) {
      func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
    }
    add(value);
    System.out.println(contains(value));
  }
} 

class SimpleHash {//这玩意相当于C++中的结构体 

  private int cap;
  private int seed; 

  public SimpleHash(int cap, int seed) {
    this.cap = cap;
    this.seed = seed;
  } 

  public int hash(String value) {//字符串哈希,选取好的哈希函数很重要
    int result = 0;
    int len = value.length();
    for (int i = 0; i < len; i++) {
      result = seed * result + value.charAt(i);
    }
    return (cap - 1) & result;
  }
} 

总结:布隆过滤器是对哈希算法的一种创新,而且需要消耗的空间也很小,错误率很低。总之这种创新的思路很值得学习,是一种对bit这种数据类型的运用。

以上这篇布隆过滤器(Bloom Filter)的Java实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
布隆过滤器
布隆过滤器实现、布隆过滤器 java、filter过滤器的实现、java filter过滤器、java xssfilter过滤器,以便于您获取更多的相关知识。

时间: 2024-10-28 11:21:10

布隆过滤器(Bloom Filter)的Java实现方法_java的相关文章

布隆过滤器Bloom Filter算法的Java实现(用于去重)

在日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个 集合中.比如在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断它是否在已知的字典中):在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上:在网络爬虫里,一个网址是否被访问过等等.最直接的方法就是将集合中全部的元素存在计算机中,遇到一个新 元素时,将它和集合中的元素直接比较即可.一般来讲,计算机中的集合是用哈希表(hash table)来存储的.它的好处是快速准确,缺点是费存储空间.当集合比较小时,这个问题不显著,但

java 过滤器模式(Filter/Criteria Pattern)详细介绍_java

java 过滤器模式(Filter/Criteria Pattern) 过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准.  过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算

在maven工程里运行java main方法_java

在Maven工程里运行Java main方法 复制代码 代码如下: mvn compilemvn exec:java -Dexec.mainClass="com.vineetmanohar.module.Main"mvn exec:java -Dexec.mainClass="com.vineetmanohar.module.Main" -Dexec.args="arg0 arg1 arg2"

布隆过滤器(转)

      布隆过滤器 假如有1亿个不重复的正整数(大致范围已知),但是只有1G的内存可用,如何判断该范围内的某个数是否出现在这1亿个数中?最常用的处理办法是利用位图,1*108/1024*1024*8=11.9,也只需要申请12M的内存.但是如果是1亿个邮件地址,如何确定某个邮件地址是否在这1亿个地址中?这个时候可能大家想到的最常用的办法就是利用Hash表了,但是大家可以细想一下,如果利用Hash表来处理,必须开辟空间去存储这1亿个邮件地址,因为在Hash表中不可能避免的会发生碰撞,假设一个邮

java中Filter过滤器处理中文乱码的方法_java

注意问题:在学习用selvert的过滤器filter处理中文乱码时,在filter配置初始化时用了utf-8处理中文乱码,而在提交的jsp页面中却用了gbk.虽然两种都可以出来中文乱码,但是却造成了处理乱码的格式不一致.所以编译出错. 解决方法:所有地方都用utf-8或gbk 复制代码 代码如下: //过滤器类CharactorFilter.jsppackage cn.com.Filter; import java.io.IOException; import javax.servlet.Fil

爬虫技术之bloom filter(含java代码)

在爬虫系统中,在内存中维护着两个关于URL的队列,ToDo队列和Visited队列,ToDo队列存放的是 爬虫从已经爬取的网页中解析出来的即将爬取的URL,但是网页是互联的,很可能解析出来的URL是已经 爬取到的,因此需要VIsited队列来存放已经爬取过的URL.当爬虫从ToDo队列中取出一个URL的时候, 先和Visited队列中的URL进行对比,确认此URL没有被爬取后就可以下载分析来.否则舍弃此URL,从 Todo队列取出下一个URL继续工作. 然后,我们知道爬虫在爬取网页时,网页的量是

海量数据处理利器之布隆过滤器

      看见了海量数据去重,找到停留时间最长的IP等问题,有博友提到了Bloom Filter,我就查了查,不过首先想到的是大叔,下面就先看看大叔的风采.              一.布隆过滤器概念引入       (Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(

[算法系列之十]大数据量处理利器:布隆过滤器

[引言] 在日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个集合中.比如在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断 它是否在已知的字典中):在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上:在网络爬虫里,一个网址是否被访问过等等.最直接的方法就是将集合中全部的元素存在计算机中,遇到一个新 元素时,将它和集合中的元素直接比较即可.一般来讲,计算机中的集合是用哈希表(hash table)来存储的.它的好处是快速准确,缺点是费存储空间.当集合比较小时,这个问题

BloomFilter(布隆过滤器)简介

判断一个元素是否在一个集合中,有很多种方法,这里介绍一个用在Google的搜索系统中的一个很有意思的算法. 如何判断一个元素是否在一个集合中: 首先,我们假设,元素的数量为n,元素的长度为m. 最简单的方法: 用一个数组存储,然后每次for循环来查找.忽略元素比较的时间,一次查询的时间复杂度是O(n),空间复杂度为O(n*m).在数据量不大的情况下,这是很不错的选择. 采用树状索引: 常用的二叉树,或者btree这类的索引方法也是不错的选择.它们将时间复杂度缩减到O(nlogn),空间复杂度依然