基于Java实现简化版本的布隆过滤器
一、布隆过滤器:
布隆过滤器(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实现简化版本的布隆过滤器的更多相关文章
- 一致性哈希做负载均衡,基于dubbo的简化版本,超级简单容易理解!!!
一致性哈希算法原理以及做分布式存储.一定先看:一致性哈希算法 dubbo提供了四种负载均衡实现:权重随机算法,最少活跃调用数算法,一致性哈希算法,加权轮询算法. 本文基于开源项目:guide-rpc- ...
- Redis: 缓存过期、缓存雪崩、缓存穿透、缓存击穿(热点)、缓存并发(热点)、多级缓存、布隆过滤器
Redis: 缓存过期.缓存雪崩.缓存穿透.缓存击穿(热点).缓存并发(热点).多级缓存.布隆过滤器 2019年08月18日 16:34:24 hanchao5272 阅读数 1026更多 分类专栏: ...
- 简化布隆过滤器——BitMap
简化布隆过滤器--BitMap 前言 前段开发项目试就发现,一部分的代码实现存在着一些性能上的隐患.但当时忙于赶进度和由于卡发中的不稳定因素,想了许多解决方案也没有机会实施.最近,正好趁个机会进行一系 ...
- 布隆过滤器(Bloom Filters)的原理及代码实现(Python + Java)
本文介绍了布隆过滤器的概念及变体,这种描述非常适合代码模拟实现.重点在于标准布隆过滤器和计算布隆过滤器,其他的大都在此基础上优化.文末附上了标准布隆过滤器和计算布隆过滤器的代码实现(Java版和Pyt ...
- Flink去重统计-基于自定义布隆过滤器
一.背景说明 在Flink中对流数据进行去重计算是常有操作,如流量域对独立访客之类的统计,去重思路一般有三个: 基于Hashset来实现去重 数据存在内存,容量小,服务重启会丢失. 使用状态编程Val ...
- 布隆过滤器的java实现
package com.kaikeba.data.jobspider.util; import java.util.BitSet; public class Bloomfilter { private ...
- 基于Redis扩展模块的布隆过滤器使用
什么是布隆过滤器?它实际上是一个很长的二进制向量和一系列随机映射函数.把一个目标元素通过多个hash函数的计算,将多个随机计算出的结果映射到不同的二进制向量的位中,以此来间接标记一个元素是否存在于一个 ...
- 布隆过滤器(Bloom Filter)-学习笔记-Java版代码(挖坑ing)
布隆过滤器解决"面试题: 如何建立一个十亿级别的哈希表,限制内存空间" "如何快速查询一个10亿大小的集合中的元素是否存在" 如题 布隆过滤器确实很神奇, 简单 ...
- 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想
转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
随机推荐
- flutter 解析json
关于flutter 解析json 自己看了几天,最近才大概知道是怎么个情况. 首先 要处理的 是后端返回的数据 ,如果是直接请求的话返回的是json 字符串 然后要把字符串转成对象,有几种方式参考 第 ...
- 如何进行PDF页码编排,如何调整PDF页码顺序
PDF文件的页码顺序如何进行调整?许多小伙伴们都不知道,我们在编辑的时候只知道PDF文件的编辑方法,但是调整页码的顺序我们或许不会,但是如何去进行操作呢?看小编的方法吧!如果我们想要修改PDF文件中的 ...
- java类型转化
Java中的父类/子类相互转化问题: 子类可以转成父类:此时子类能调用父类中定义的方法和变量,如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法 父类转成子类:1.如 ...
- 【Idea】idea code style配置eclipse code formatter
在eclipse中有自动配置code style的功能 ,但是idea上却没有,这个时候需要自己手工配置 1. 在idea中找到Preference->Plugins->Browse re ...
- Centos 部署.net Core
1.安装net core框架 sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc sudo sh -c 'echo ...
- Angular动画——路由动画及高阶动画函数
一.路由动画 路由动画需要在host元数据中指定触发器.动画注意不要过多,否则适得其反. 内容优先,引导用户去注意到某个内容.动画只是辅助手段. 定义一个进场动画,一个离场动画. 因为进场动画和离场动 ...
- this指向及改变this指向的方法
一.函数的调用方式决定了 this 的指向不同,但总的原则,this指的是调用函数的那个对象: 1.普通函数调用,此时 this 指向 全局对象window function fn() { conso ...
- xiao_ren
- java并发编程可见性与线程封闭
可见性 所谓可见性,指的是当一个线程修改了对象的状态后,其他线程能够看到该对象发生的变化.在单线程环境下,向某个变量写入值,然后在后面的操作再读取,在这个过程中该变量的值对该线程来说总是可见.但是,在 ...
- python程序入门 基础教程
1.VSCode基础使用+VSCode调试python程序入门 2.pip 安装 3.scrapy安装 4.python解析xml