一、布隆过滤器:

  布隆过滤器(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. OpenStack--glance组件镜像服务

    glance介绍 Glance 是 OpenStack 项目中负责镜像管理的模块,其功能包括虚拟机镜像的查找,注册和检索等.Glance 提供 Restful API 可以查询虚拟机镜像的 metad ...

  2. 《剑指offer》扑克牌顺子

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

  3. 用vue实现点击编辑按钮将li变为可以输入文本的input

    <template> <li v-if='flag'><span @click='edit()'>点击一下</span></li> < ...

  4. maven安装与环境变量配置

    一.什么是maven Maven基于项目对象模型(POM Project Object Model),可以通过一小段描述信息(配置文件)来管理项目的构建.报告和文档的软件项目管理工具. 同时也是跨平台 ...

  5. Linux时间同步问题

    一.调整时区 sudo tzselect 选择时区 Asia-> China-> Beijing Time->Yes 二.同步时间 ntpdate cn.pool.ntp.org 三 ...

  6. js过滤html标签

    function deleteHtmlTag(str){ str = str.replace(/<[^>]+>|&[^>]+;/g,"").trim ...

  7. docker容器时间与宿主机时间不一致问题

    该问题是宿主机和容器时去不一致导致的. 把本机时区复制到宿主机即可: docker cp /etc/localtime a9c27487faf4:/etc/localtime 然后重启容器.

  8. 我的Python笔记03

    摘要: 声明:本文整理借鉴金角大王的Python之路,Day3 - Python基础3,仅供本人学习使用!!!   本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4 ...

  9. MockPlus原型设计介绍

    MockPlus原型设计介绍 在第八周的课堂上,王文娟老师在校园系统上发布了对于自行选择的原型设计软件进行资料查找以及自学的任务.因为之前的课程学习需要,我们已经大概掌握了原型设计软件Axure的使用 ...

  10. kvm虚拟机迁移

    一.迁移简介 迁移: 系统的迁移是指把源主机上的操作系统和应用程序移动到目的主机,并且能够在目的主机上正常运行.在没有虚拟机的时代,物理机之间的迁移依靠的是系统备份和恢复技术.在源主机上实时备份操作系 ...