手撸布隆过滤器
2021/12/21 23:51:26
本文主要是介绍手撸布隆过滤器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一个低配版BloomFilter
public class MyBloomFilter { // 后面hash函数会用到,用来生成不同的hash值,可以随便给,但别给奇数 private final int[] ints = {6, 8, 16, 38, 58, 68}; // 统计当前对象数量 private Integer currentBeanCount = 0; // 你的布隆过滤器容量 private int DEFAULT_SIZE = Integer.MAX_VALUE; // bit数组,用来存放结果 private final BitSet bitSet = new BitSet(DEFAULT_SIZE); public MyBloomFilter() { } public MyBloomFilter(int size) { if (size > Integer.MAX_VALUE) throw new RuntimeException("size is too large"); if (size <= (2 << 8)) throw new RuntimeException("size is too small"); DEFAULT_SIZE = size; } // 获取当前过滤器的对象数量 public Integer getCurrentBeanCount() { return currentBeanCount; } // 计算出key的hash值,并将对应下标置为1 public void push(Object key) { Arrays.stream(ints).forEach(i -> bitSet.set(hash(key, i))); currentBeanCount++; } // 判断key是否存在,true不一定说明key存在,但是false一定说明不存在 public boolean contain(Object key) { boolean result = true; for (int i : ints) { result = result && bitSet.get(hash(key, i)); } return result; } // hash算法,借鉴了hashmap的算法,利用i对同个key生成一组不同的hash值 private int hash(Object key, int i) { int h; int index = key == null ? 0 : (DEFAULT_SIZE - 1 - i) & ((h = key.hashCode()) ^ (h >>> 16)); return index > 0 ? index : -index; } }
它在用作判断对象 是否存在 时有误判率,误判率随着对象数量增加而增加
但是用作判断对象 是否不存在 时,没有误判率
一亿条数据去重
public static void main(String[] args) { //实例化 MyBloomFilter filter = new MyBloomFilter(); for (int i = 0; i < 20; i++) { //push到BloomFilter getPersonList(500000).forEach(person -> filter.push(person)); } //push一个确定的对象 filter.push(getFixedPerson(now)); //判断这个对象是否存在 long start = System.currentTimeMillis(); System.out.println(filter.contain(getFixedPerson(now))); long end = System.currentTimeMillis() - start; System.out.println("bloomFilter内对象数量:" + filter.getCurrentBeanCount()); System.out.println("耗时(ms):" + end + ",消耗内存(M):" + (ObjectSizeCalculator.getObjectSize(filter) / (1024 * 1024))); }
原理
就是通过对比hash算法计算出来的下标,但注意,是对比一组,而不是一次,一次hash结果只对应一个下标
把同一个key进行多次hash运算,将hash出来的下标放入数组,数组默认全为0,放入元素后该下标就为1,后面判断是否存在元素的时候也是进行同样次数的hash运算,看下结果对应的所有下标是否全为1,若全为1,则代表该key可能存在,若存在不为1的,则说明该key一定不存在;
默认bit数组:[0,0,0,0,0,0]
比方说有个key计算出的一组hash下标是0,2,5
对应位bit数组:[1,0,1,0,0,1]
判断某个未知key是否存在时候,假设我们计算出来的下标是0,2,4
对应位数组:[1,0,1,0,1,0]
此时位数组内5对应下标值为0,而已知key位数组的5对应下标位1,说明这两个key一定不同
相反,如果某个key计算出来的下标为[1,0,1,0,0,1],只能说这个key可能存在,因为这几个位置可能是其它key计算出来的
摘自:https://blog.csdn.net/qq_33709582/article/details/122046773
这篇关于手撸布隆过滤器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南