一、布隆过滤器:

  布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。布隆过滤器是与哈希算法是相关的,是工业实践上常用的算法,之前我们使用HashMap或者HashSet来查找重复的话也是可以的,但是对于在数据量比较大的情况下去查询那么速度就比较慢了,这个时候对于大的数据量来进行检索使用布隆过滤查找速度就比较快。

  如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树、散列表(又叫哈希表,HashTable)等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,同时检索速度也越来越慢,上述三种结果的检索时间分别为O(n),O(logn),O(n/k)。

  布隆过滤器的原理是,当一个元素被加入集合时,通过k个散列函数将这个元素映射成一个位数组(位阵列 Bit array)中的k个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在,如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。

    

  下面使用md5算法计算出哈希值并在对应的位图上置1,我们也可以使用其他的哈希函数计算出哈希值比如直接取余法,乘法这些,使用任何的哈希算法计算出来的哈希值对于检索的结果是没有影响的,只是检索的效率会有所不同。并且这里使用到了BigInteger类用来处理生成的比较大的数字。

二、代码:

 import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger; // 扩展知识 不要求掌握
/** 简化版本的布隆过滤器的实现 */
public class BloomFilter {
public static final int NUM_SLOTS = 1024 * 1024 * 8;// 位图的长度
public static final int NUM_HASH = 8;// hash函数的个数,一个hash函数的结果用于标记一个位
private BigInteger bitmap = new BigInteger("0");// 位图 public static void main(String[] args) {
// 测试代码
BloomFilter bf = new BloomFilter();
ArrayList<String> contents = new ArrayList<>();
contents.add("sldkjelsjf");
contents.add("ggl;ker;gekr");
contents.add("wieoneomfwe");
contents.add("sldkjelsvrnlkjf");
contents.add("ksldkflefwefwefe"); for (int i = 0; i < contents.size(); i++) {
bf.addElement(contents.get(i));
}
System.out.println(bf.check("sldkjelsvrnlkjf")); // true
System.out.println(bf.check("sldkjelnlkjf")); // false
System.out.println(bf.check("ggl;ker;gekr")); // true
} /** 将message+n映射到0~NUM_SLOTS-1之间的一个值 */
private int hash(String message, int n) {
message = message + String.valueOf(n);
try {
MessageDigest md5 = MessageDigest.getInstance("md5");// 将任意输入映射成128位(16个字节)整数的hash函数
byte[] bytes = message.getBytes();
md5.update(bytes);
byte[] digest = md5.digest();
BigInteger bi = new BigInteger(digest);// 至此,获得message+n的md5结果(128位整数) return Math.abs(bi.intValue()) % NUM_SLOTS;
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(BloomFilter.class.getName()).log(Level.SEVERE, null, ex);
}
return -1;
// return (int)Math.abs(HashFunctions.bernstein(message,NUM_SLOTS));
} /*
* 处理原始数据 1.hash1(msg)标注一个位…… hash的值域0~NUM_SLOTS-1
*/
public void addElement(String message) {
for (int i = 0; i < NUM_HASH; i++) {
int hashcode = hash(message, i);// 代表了hash1,hash2……hash8
// 结果,用于标注位图的该位为1
if (!bitmap.testBit(hashcode)) {// 如果还不为1
// 标注位图的该位为1
bitmap = bitmap.or(new BigInteger("1").shiftLeft(hashcode));
}
} } public boolean check(String message) {
for (int i = 0; i < NUM_HASH; i++) {
int hashcode = hash(message, i);
// hashcode代表一个位置
if (!this.bitmap.testBit(hashcode)) {
// 如果位图的该位为0,那么message一定不存在
return false;
}
}
return true;// 不精确,有可能误判
}
}

基于Java实现简化版本的布隆过滤器的更多相关文章

  1. 一致性哈希做负载均衡,基于dubbo的简化版本,超级简单容易理解!!!

    一致性哈希算法原理以及做分布式存储.一定先看:一致性哈希算法 dubbo提供了四种负载均衡实现:权重随机算法,最少活跃调用数算法,一致性哈希算法,加权轮询算法. 本文基于开源项目:guide-rpc- ...

  2. Redis: 缓存过期、缓存雪崩、缓存穿透、缓存击穿(热点)、缓存并发(热点)、多级缓存、布隆过滤器

    Redis: 缓存过期.缓存雪崩.缓存穿透.缓存击穿(热点).缓存并发(热点).多级缓存.布隆过滤器 2019年08月18日 16:34:24 hanchao5272 阅读数 1026更多 分类专栏: ...

  3. 简化布隆过滤器——BitMap

    简化布隆过滤器--BitMap 前言 前段开发项目试就发现,一部分的代码实现存在着一些性能上的隐患.但当时忙于赶进度和由于卡发中的不稳定因素,想了许多解决方案也没有机会实施.最近,正好趁个机会进行一系 ...

  4. 布隆过滤器(Bloom Filters)的原理及代码实现(Python + Java)

    本文介绍了布隆过滤器的概念及变体,这种描述非常适合代码模拟实现.重点在于标准布隆过滤器和计算布隆过滤器,其他的大都在此基础上优化.文末附上了标准布隆过滤器和计算布隆过滤器的代码实现(Java版和Pyt ...

  5. Flink去重统计-基于自定义布隆过滤器

    一.背景说明 在Flink中对流数据进行去重计算是常有操作,如流量域对独立访客之类的统计,去重思路一般有三个: 基于Hashset来实现去重 数据存在内存,容量小,服务重启会丢失. 使用状态编程Val ...

  6. 布隆过滤器的java实现

    package com.kaikeba.data.jobspider.util; import java.util.BitSet; public class Bloomfilter { private ...

  7. 基于Redis扩展模块的布隆过滤器使用

    什么是布隆过滤器?它实际上是一个很长的二进制向量和一系列随机映射函数.把一个目标元素通过多个hash函数的计算,将多个随机计算出的结果映射到不同的二进制向量的位中,以此来间接标记一个元素是否存在于一个 ...

  8. 布隆过滤器(Bloom Filter)-学习笔记-Java版代码(挖坑ing)

    布隆过滤器解决"面试题: 如何建立一个十亿级别的哈希表,限制内存空间" "如何快速查询一个10亿大小的集合中的元素是否存在" 如题 布隆过滤器确实很神奇, 简单 ...

  9. 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想

    转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton ...

随机推荐

  1. 逻辑卷管理(linux)

    (创建分区)1.fdisk /dev/sdb2.n3default4.default5.+200M6.w7.partprobe(更新分区)8mkfs.ext4 /dev/sdb1//格式化sdb1.. ...

  2. Joone

    JOONE 一.什么是JOONE? 1.Joone是一个免费的神经网络框架来创建,训练和测试人造神经网络.目标是为最热门的Java技术创造一个强大的环境,为热情和专业的用户.2.Joone由一个中央引 ...

  3. WPF自定义仪表盘控件

    闲来无事,分享一个仪表盘 源码: 直接复制代码即可运行,=.=! <Window x:Class="TGP.InstrumentationDemo.MainWindow" x ...

  4. AngualrJS之自定义指令

    一.指令 指令directive是AngularJS的核心之一 包括 - 用于扩展HTML元素.属性的指令 - 执行特定功能的指令 - 自定义指令 内置指令基本上都是以ng-开头 二.内置指令 1.属 ...

  5. Codeforces 959F Mahmoud and Ehab and yet another xor task 线性基 (看题解)

    Mahmoud and Ehab and yet another xor task 存在的元素的方案数都是一样的, 啊, 我好菜啊. 离线之后用线性基取check存不存在,然后计算答案. #inclu ...

  6. 分布式缓存技术之Redis_01数据结构分析

    目录 官网 1. 分布式缓存技术的应用 2. Redis的安装指引 官网  redis.io  redisDoc 1. 分布式缓存技术的应用 2. Redis的安装指引 官网下载安装包 redis-5 ...

  7. 第二项目AIaisell(易销宝)

    一.什么是报表 向上级报告情况的表格.简单的说:报表就是用表格.图表等格式来动态显示数据,可以用公式表示为:“报表 = 多样的格式 + 动态的数据” 表格:详细数据 图表: 直观 二.表格数据展示 2 ...

  8. ECMAScript 6 之 let 和 const 命令

    1.let基本用法 1.1.声明变量 let声明的变量只在它所在的代码块有效. 1.2.不存在变量提升 var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined: let命令 ...

  9. 2018-2019 20165220 网络对抗 Exp5 MSF基础

    实验任务 1.1一个主动攻击实践,如ms08_067; (1分) 1.2 一个针对浏览器的攻击,如ms11_050:(1分) 1.3 一个针对客户端的攻击,如Adobe:(1分) 1.4 成功应用任何 ...

  10. C#WebApi 接口参数不再困惑:传参详解

    前言:还记得刚使用WebApi那会儿,被它的传参机制折腾了好久,查阅了半天资料.如今,使用WebApi也有段时间了,今天就记录下API接口传参的一些方式方法,算是一个笔记,也希望能帮初学者少走弯路.本 ...