布隆过滤器BloomFilter java实现和使用示例

布隆过滤器的java实现代码, 自己实现的布隆过滤器和使用示例, Google的Guava包里面也有BloomFilter的实现。

MyBloomFilter.java

package cn.tekin.tools;

import java.util.Arrays;
import java.util.BitSet;

/**
 * 布隆过滤器 JAVA实现代码
 * @author Tekin <tekintian@gmail.com>
 * @QQ 932256355
 */
public class MyBloomFilter {
    // 二进制向量(数组)的位数,
    // 2算术左移29 结果为 1073741824  10亿7千万bit
    public static final int BIT_CAP = 2 << 29;
    // 初始化BitSet容器
    private final BitSet bits = new BitSet(BIT_CAP);
    // 初始化Hash对象
    private final Hash h = new Hash(BIT_CAP, 37);

    public MyBloomFilter() {

    }

    /**
     * 将要判断的数据(字符串)添加到过滤器中
     *
     * @param val
     */
    public void addValue(String val) {
        if (val != null) {
            // 将字符串val 转换为整数 并作为set集合的key存入set集合,值为true
            bits.set(h.hash(val), true);
        }
    }

    /**
     * 判断字符串是否包含在布隆过滤器中
     *
     * @param val
     * @return
     */
    public boolean contains(String val) {
        if (val == null || val.isEmpty()) return false;
        // 将要比较的字符串重新以上述方法计算hash值, 再根据这个值为key从bitset里面获取对应的值
        int bitKey = h.hash(val);
        return bits.get(bitKey);
    }

    /**
     * 静态内部类
     */
    private static class Hash {
        // 二进制向量数组大小
        private final int size;

        // 随机数种子
        private final int seed;

        /**
         * 构造函数
         *
         * @param cap
         * @param seed
         */
        public Hash(int cap, int seed) {
            this.size = cap;
            this.seed = seed;
        }

        /**
         * 计算hash值
         * 与运算 &  规则 :都为1时才为1
         *
         * @param val
         * @return
         */
        public int hash(String val) {
            int result = 0;
            int len = val.length();
            // Hash算法 加权求和
            for (int i = 0; i < len; i++) {
                result += seed * result + val.charAt(i);
            }
            // 取模, 得到具体二进制数组下标
            return (size - 1) & result;
        }

        /**
         * 字符串hashCode计算 使用java内置的hashcode计算方法
         * <p>
         * 与运算 &  规则 :都为1时才为1
         *
         * @param val
         * @return
         */
        public int hcode(String val) {
            // 这里进行与操作 确保返回数值为正数
            return (size - 1) & Arrays.hashCode(val.getBytes());
        }
    }
}

布隆过滤器测试代码

package cn.tekin;

import cn.tekin.tools.MyBloomFilter;

import java.util.HashMap;
import java.util.UUID;

public class Main {
    public static void main(String[] args) {

        System.out.printf("Hello and welcome!");

        MyBloomFilter mybf = new MyBloomFilter();
        mybf.addValue("www.tekin.cn");

        // 测试数据总数
        int totalNum=1000000;
        HashMap<Integer, String> testmap=new HashMap<Integer, String>(totalNum);
        for (int i = 0; i < totalNum; i++) {

            String val = UUID.randomUUID().toString();
            testmap.put(i, val);

            mybf.addValue(val);
        }
        mybf.addValue("www.baidu.com");
        mybf.addValue("www.qq.com");

        System.out.printf("\nwww.qq.com 查找结果:%b \n",mybf.contains("www.qq.com"));

        int errCnt=0;

        for (int i = 0; i < totalNum; i++) {
            if (!mybf.contains(testmap.get(i))) {
                System.out.printf("误报了,索引为:%d 值为:%s ", i, testmap.get(i));
                errCnt++;
            }
        }

        System.out.printf("\n总处理数据数:%d 条 误报数:%d %n",totalNum, errCnt);


    }
}

布隆过滤器主要用于数据的存在/不存在判断, 如判断redis中是否有指定的key , 防止redis缓存击穿, 用于垃圾邮件过滤等。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值