一、布隆过滤器:

  布隆过滤器(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. vertx的ShardData共享数据

    数据类型 一共4种 synchronous shared maps (local) asynchronous maps (local or cluster-wide) asynchronous loc ...

  2. EndNote中文文献导入出错和数量限制解决

    发现之前记录的存在忽略,把存在的一个重要问题遗漏了,Endnote中文文献导入无法导入,软件奔溃问题,现在在原先基础上补上(补到最后): ..一路绿色φ(>ω<*) φ(>ω< ...

  3. MongoD 语法

    MongoD 语法 1.常用 1 .查看有哪些库 > show dbs; admin 0.000GB config 0.000GB local 0.000GB 2 .当前库,只存在于内存中 &g ...

  4. About The Order of The Declarations And Definition When Making a Member Function a Friend.关于使类成员成为另一个类友元函数的声明顺序和定义。

    If only member function clear of WindowMgr is a friend of Screen, there are some points need to note ...

  5. 《物联网框架ServerSuperIO教程》- 23.动态数据接口增加缓存,提高数据输出到OPCServer和(实时)数据库的效率

     22.1   概述及要解决的问题 设备驱动有DeviceDynamic接口,可以继承并增加新的实时数据属性,每次通讯完成后更新这些属性数据.原来是通过DeviceDynamic接口实体类反射的方式获 ...

  6. Python学习(四十三)—— Djago-admin管理工具

    一.admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INSTAL ...

  7. UOJ#104. 【APIO2014】Split the sequence 动态规划 斜率优化

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ104.html 题解 首先证明一个结论:对于一种分割方案,分割的顺序不影响最终结果. 证明:对于树 a[x] 和 a[y] ...

  8. 20165319 Exp1 PC平台逆向破解

    本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getShell,会返 ...

  9. Invitation Cards POJ - 1511 (双向单源最短路)

    In the age of television, not many people attend theater performances. Antique Comedians of Malidine ...

  10. Android- APP 秒开

    Android- APP 秒开 1. 启动APP 时白屏或者黑屏 现象:当启动APP 时,会有一个白屏或者黑屏一闪而过,然后才会显示出主界面. 这是因为,我们新打开一个应用,系统会为这个应用创建一个进 ...