ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 布隆过滤器

2021-12-06 21:59:12  阅读:168  来源: 互联网

标签:hash BigDecimal 布隆 existsCount mightExistsCount 过滤器 Java


实际上就是一个额很长的二进制向量![在这里插入图片描述](https://www.icode9.com/i/ll/?i=fcc694c61f324e43a1f85686bacbfd4f.png?,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU3BhcmE=,size_20,color_FFFFFF,t_70,g_se,x_1
布隆过滤器本质上是一个巨大的二进制数组,以Redis中的布隆过滤器实现为例,Redis中的布隆过滤器底层是一个大型位数组(二进制数组)+多个无偏hash函数。

多个无偏hash函数:

无偏hash函数就是能把元素的hash值计算的比较均匀的hash函数,能使得计算后的元素下标比较均匀的映射到位数组中。

如下就是一个简单的布隆过滤器示意图,其中k1、k2代表增加的元素,a、b、c即为无偏hash函数,最下层则为二进制数组。

在这里插入图片描述
注意,这里abc是三个Hash函数,k1和k2是两个要存进来的数据。存进来以后,某几个位置上就被置为1。

在查询的时候,要计算该元素的三个hash函数,然后去找每个位置上的0或者1,如果所有的都是1,就是存在,如果有任何一个位置为0,就不存在。

但是,这也会导致误判,因为某些元素会计算得出相同的位,也就是说在计算中会出现误判——把不存在于数据中的元素当成了存在的。

同样,也不能删除,因为删除会删除掉其他数据。

public static void main(String[] args){
        int capacity = 100000;
        /** 初始化容量为10万大小的字符串布隆过滤器,默认误差率为0.03
         *  布隆过滤器容量为10万并非指bitmap的长度就是10万,因为需要考虑到存在hash冲突的情况,所以bitmap的实际长度要比10万要大很多
         *  bitmap长度比需要存在的数据量大小越大,误差率会越低
         * */
        BloomFilter bloomFilter =BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), capacity);

        Set<String> sets = new HashSet<>();
        List<String> lists = new ArrayList<>();

        for (int i =0;i< capacity; i++){
            String str = UUID.randomUUID().toString();
            bloomFilter.put(str);
            sets.add(str);
            lists.add(str);
        }

        int existsCount = 0;
        int mightExistsCount = 0;

        for(int i=0;i<10000;i++){
            //如果i为100倍数,取实际的值;否则就随机一个字符串
            String data = i%100==0?lists.get(i/100):UUID.randomUUID().toString();
            /** 通过布隆过滤器判断字符串是否存在*/
            if(bloomFilter.mightContain(data)){
                /** 如果布隆过滤器认为存在,则表示可能存在的数量mightExistsCount自增1*/
                mightExistsCount++;
                /** 如果set中存在则existsCount自增1*/
                if(sets.contains(data)){
                    existsCount++;
                }
            }
        }

        //测试总次数
        BigDecimal total = new BigDecimal(10000);
        //错误总次数
        BigDecimal error = new BigDecimal(mightExistsCount - existsCount);
        //误差率
        BigDecimal rate = error.divide(total, 2, BigDecimal.ROUND_HALF_UP);

        System.out.println("初始化10万条数据,判断100个真实数据,9900个不存在数据");
        System.out.println("实际存在的字符串个数为:" + existsCount);
        System.out.println("布隆过滤器认为存在的个数为:" + mightExistsCount);
        System.out.println("误差率为:" + rate.doubleValue());
    }

影响误判率的主要因素就是 布隆过滤器数据所占的空间大小,以及哈希方法的个数。

如果需要误判率低,就需要布隆过滤器空间更大,以及哈希方法更多。

标签:hash,BigDecimal,布隆,existsCount,mightExistsCount,过滤器,Java
来源: https://blog.csdn.net/qq_37772958/article/details/121756825

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有