ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

布隆过滤器详解(BloomFilter)以及其实现介绍

2022-01-09 14:30:54  阅读:131  来源: 互联网

标签:int 元素 布隆 SimpleHash 详解 过滤器 BloomFilter public


一、 三种去重方式

  • 1.HashSet
    使用java中的HashSet不能重复的特点去重。优点是容易理解。使用方便。
    缺点:占用内存大,性能较低。

  • 2.Redis去重
    使用Redis的set进行去重。优点是速度快(Redis本身速度就很快),而且去重不会占用爬虫服务器的资源,可以处理更大数据量的数据爬取。
    缺点:需要准备Redis服务器,增加开发和使用成本。

  • 3.布隆过滤器(BloomFilter)
    使用布隆过滤器也可以实现去重。优点是占用的内存要比使用HashSet要小的多,也适合大量数据的去重操作。
    缺点:有误判的可能。没有重复可能会判定重复,但是重复数据一定会判定重复。

二、布隆过滤器介绍

布隆过滤器 (Bloom Filter)是由Burton Howard Bloom于1970年提出,它是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。在垃圾邮件过滤的黑白名单方法、爬虫(Crawler)的网址判重模块中等等经常被用到。
哈希表也能用于判断元素是否在集合中,但是布隆过滤器只需要哈希表的1/8或1/4的空间复杂度就能完成同样的问题。布隆过滤器可以插入元素,但不可以删除已有元素。其中的元素越多,误报率越大,但是漏报是不可能的。

原理:
布隆过滤器需要的是一个位数组(和位图类似)和K个映射函数(和Hash表类似),在初始状态时,对于长度为m的位数组array,它的所有位被置0。

在这里插入图片描述

对于有n个元素的集合S={S1,S2…Sn},通过k个映射函数{f1,f2,…fk},将集合S中的每个元素Sj(1<=j<=n)映射为K个值{g1,g2…gk},然后再将位数组array中相对应的array[g1],array[g2]…array[gk]置为1:

在这里插入图片描述

如果要查找某个元素item是否在S中,则通过映射函数{f1,f2,…fk}得到k个值{g1,g2…gk},然后再判断array[g1],array[g2]…array[gk]是否都为1,若全为1,则item在S中,否则item不在S中。

布隆过滤器会造成一定的误判,因为集合中的若干个元素通过映射之后得到的数值恰巧包括g1,g2,…gk,在这种情况下可能会造成误判,但是概率很小。

三、布隆过滤器实现

//布隆过滤器
public class BloomFilter {

   /* BitSet初始分配2^24个bit */
   private static final int DEFAULT_SIZE = 1 << 24;

   /* 不同哈希函数的种子,一般应取质数 */
   private static final int[] seeds = new int[] { 5, 7, 11, 13, 31, 37 };

   private BitSet bits = new BitSet(DEFAULT_SIZE);

   /* 哈希函数对象 */
   private SimpleHash[] func = new SimpleHash[seeds.length];

   public BloomFilter() {
      for (int i = 0; i < seeds.length; i++) {
         func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
      }
   }

   // 将url标记到bits中
   public void add(String str) {
      for (SimpleHash f : func) {
         bits.set(f.hash(str), true);
      }
   }

   // 判断是否已经被bits标记
   public boolean contains(String str) {
      if (StringUtils.isBlank(str)) {
         return false;
      }

      boolean ret = true;
      for (SimpleHash f : func) {
         ret = ret && bits.get(f.hash(str));
      }

      return ret;
   }

   /* 哈希函数类 */
   public static class SimpleHash {
      private int cap;
      private int seed;

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

      // hash函数,采用简单的加权和hash
      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;
      }
   }
}

标签:int,元素,布隆,SimpleHash,详解,过滤器,BloomFilter,public
来源: https://blog.csdn.net/weixin_45829957/article/details/122393199

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有